В чем разница между:
new Promise(function(res, rej) {
res("aaa");
})
.then(function(result) {
return "bbb";
})
.then(function(result) {
console.log(result);
});
и это:
new Promise(function(res, rej) {
res("aaa");
})
.then(function(result) {
return Promise.resolve("bbb");
})
.then(function(result) {
console.log(result);
});
Я спрашиваю, как я получаю другое поведение, используя Angular и $ http сервис с цепочкой .then (). Слишком много кода, поэтому сначала пример выше.
javascript
angularjs
promise
q
spirytus
источник
источник
Promise.resolve()
втором примере нет необходимости.then
обработчика нет ничего плохого , на самом деле, это ключевой аспект спецификации обещаний, что вы можете это сделать.then
s - термин «другие языки» для этого - этоthen
и a,map
и aflatMap
.new Promise((res, rej) => { return fetch('//google.com').then(() => { return "haha"; }) }).then((result) => alert(result));
этот код будет зависать (не разрешаться вечно). Но если я перейдуreturn "haha";
наreturn res("haha");
то, это сработает и предупредит "ха-ха". Разве fetch (). Then () уже обернуло "хаха" в решенное обещание?Ответы:
Правило состоит в том, что если функция, находящаяся в
then
обработчике, возвращает значение, обещание разрешается / отклоняется с этим значением, и если функция возвращает обещание, что происходит, следующееthen
предложение будетthen
предложением, возвращаемым функцией. Таким образом, в этом случае первый пример проваливается в нормальной последовательностиthens
и выводит значения, как и следовало ожидать, во втором примере объект обещания, который возвращается, когда вы делаетеPromise.resolve("bbb")
's', является тем,then
который вызывается при сцеплении (для всех намерений и целей). Как это на самом деле работает, более подробно описано ниже.Цитирование из Обещаний / A + spec:
Ключевой момент, на который следует обратить внимание, это строка:
источник
then
обработчик возвращает обещание. +1 за спецификацию.[[Resolve]]
вызывается как дляthen
способностей, так и для значений, так что, по сути, он заключает в себе значение с обещанием, такreturn "aaa"
же, какreturn Promise.resolve("aaa")
иreturn Promise.resolve("aaa")
то же самое, посколькуreturn Promise.resolve(Promise.resolve("aaa"))
- решимость идемпотентна, вызывая его для значения, более чем один раз имеет тот же результат."aaa"
иreturn Promise.resolve("aaa")
взаимозаменяемы в состоянииthen
в любом случае?Проще говоря, внутри
then
функции обработчика:А) Когда
x
это значение (число, строка и т. Д.):return x
эквивалентноreturn Promise.resolve(x)
throw x
эквивалентноreturn Promise.reject(x)
Б) Когда
x
обещание уже выполнено (больше не ожидается):return x
эквивалентноreturn Promise.resolve(x)
, если Обещание уже выполнено.return x
эквивалентноreturn Promise.reject(x)
, если обещание уже было отклонено.C) Когда
x
ожидается обещание:return x
вернет ожидающее обещание, и оно будет оценено в последующемthen
.Подробнее об этом читайте в документации Promise.prototype.then () .
источник
Оба ваших примера должны вести себя примерно одинаково.
Значение, возвращаемое в
then()
обработчике, становится значением разрешения обещания, возвращенного из этогоthen()
. Если значение, возвращаемое внутри,.then
является обещанием, возвращенное обещаниеthen()
«примет состояние» этого обещания и разрешит / отклонит так же, как и возвращенное обещание.В первом примере вы возвращаете
"bbb"
первыйthen()
обработчик, поэтому"bbb"
он передается следующемуthen()
обработчику.Во втором примере вы возвращаете обещание, которое немедленно разрешается со значением
"bbb"
, поэтому"bbb"
оно передается следующемуthen()
обработчику. (Promise.resolve()
Здесь посторонний).Результат тот же.
Если вы можете показать нам пример, который на самом деле демонстрирует другое поведение, мы можем рассказать вам, почему это происходит.
источник
Promise.resolve();
противreturn;
?undefined
вместо"bbb"
.Вы уже получили хороший официальный ответ. Я решил добавить короткий.
Следующие вещи идентичны обещаниям / обещаниям A + :
Promise.resolve
(в вашем угловом случае это$q.when
)new $q
.then
обратного вызова.Таким образом, для обещания или простого значения X все они идентичны:
И неудивительно, что спецификация обещаний основана на процедуре разрешения обещаний, которая позволяет легко взаимодействовать между библиотеками (например, $ q и собственными обещаниями) и облегчает вашу жизнь в целом. Всякий раз, когда может произойти разрешение обещания, возникает разрешение, создающее общую согласованность.
источник
Promise.resolve().then(function(){ return x; });
? Я обнаружил, что snipped делает что-то похожее (это называется функцией внутриthen
блока). Я думал, что это более или менее похоже на тайм-аут, но это немного быстрее. jsben.ch/HIfDowith
блоке над объектом или прокси-сервером со средствомx
доступа к свойству, которое выдает исключение. В этом случае Promise.resolve (x) вызовет сгенерированную ошибку, ноPromise.resolve().then(function(){ return x; });
будет отклоненным обещанием, поскольку сгенерирована ошибка в аthen
).if (validator) { Promise.resolve().then(() => { this._cdRef.markForCheck(); }); }
. Здесь обещание не назначено, так какой смысл? Тайм-аут будет иметь (более или менее) тот же эффект, или нет?Разница лишь в том, что вы создаете ненужное обещание, когда делаете
return Promise.resolve("bbb")
. Возвращение обещания отonFulfilled()
обработчика запускает разрешение обещания . Вот как работает цепочка обещаний .источник