Разница между defer(). Обещанием и обещанием
Я знаю, что defer разделяет состояния и управление состояниями обещаний, здесь, на примере Q, обещание, возвращаемое Q.defer().promise
а также Q.Promise
совершенно другой, почему проектирование таким образом? и какая разница между этими двумя "обещаниями"
заранее спасибо
PS: в настоящее время я работаю над библиотекой Promise, выпуск и 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 есть важное различие. Конструктор обещаний безопасен.
Брось безопасность
Обещает абстрактную обработку исключений и безопасен. Если вы добавите в цепочку обещаний, это исключение преобразуется в отказ, цитируя спецификацию:
Если onFulfilled или onRejected выбрасывают исключение e, promise2 должно быть отклонено с 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);
});
Предотвращение появления целого класса ошибок программиста.