Разница между defer(). Обещание и обещание

Я знаю, что defer отделяет promises состояние управления и процесса, здесь, используя Q в качестве примера, обещание, возвращаемое Q.defer().promise и Q.Promise, совершенно иное, почему проектирование таким образом? и какая разница между этими двумя "обещаниями"

Заранее спасибо

PS: В настоящее время я работаю над библиотекой Promise, issuses и PRS: https://github.com/XiaomingJS/Xiaoming.Promise

Ответы

Ответ 1

Ну, речь идет о источнике разрешения обещаний. Q и множество других библиотек предлагают два API:

  • Устаревший defer API - в котором вы создаете отложенную версию, которую вы можете .resolve(value), и у нее есть обещание, которое вы можете вернуть.
  • Конструктор обещаний - это современный API, в котором вы создаете обещание от источника завершения.

Грубо делать:

var d = Q.defer();
setTimeout(function(){ d.resolve(); }, 1000); 
return d.promise;

То же, что и:

return new Promise(function(resolve, reject){
   setTimeout(resolve, 1000);
});

чтобы вы могли спрашивать

Зачем нам нужны два API?

Ну, сначала появился API отсрочки. Это как некоторые другие языки справляются с этим, это то, как документы справляются с этим, и как люди использовали его в первую очередь, однако - существует существенное различие между этими двумя API. Конструктор обещаний безопасен для броска.

Предотвращение безопасности

Promises абстрактная обработка исключений и безопасны для броска. Если вы забросите в цепочку обещаний, она преобразует это исключение в отказ, указав спецификацию:

Если либо onFulfilled, либо onRejected выбрасывает исключение e, prom2 должно быть отклонено с e в качестве причины

Предположим, что вы разбираете JSON из запроса XHR:

function get(){
    var d = Q.defer();
    if(cached) { // use cached version user edited in localStorage
        d.resolve(JSON.parse(cached));
    } else { // get from server
       myCallbackApi('/foo', function(res){ d.resolve(res); });
    }
}

Теперь посмотрим на версию конструктора обещаний:

function get(){
    return new Promise(function(resolve, reject){ 
        if(cached) { // use cached version user edited in localStorage
            resolve(JSON.parse(cached));
        } else { // get from server
           myCallbackApi('/foo', resolve);
        }
    });
}

Теперь предположим, что ваш сервер отправил вам недействительный JSON (или пользователь отредактировал его в недопустимое состояние), и вы его кэшировали.

В версии отсрочки - это синхронно. Поэтому вы должны в целом защищать его. В нижней версии этого нет. Использование верхней версии будет выглядеть так:

try{
  return get().catch(function(e){
     return handleException(e); // can also just pass as function
  });
} catch(e){ 
   handleException(e);
}

В нижней версии - конструктор обещаний преобразует throw в отклонения, поэтому достаточно сделать:

return get().then(function(e){
   return handleException(e);
});

Предотвращение ошибок всего класса программистов.