Ответ 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);
});
Предотвращение ошибок всего класса программистов.