Какая разница между возвращаемой стоимостью или Promise.resolve с того времени()
В чем разница между:
new Promise(function(res, rej) {
res("aaa");
})
.then(function(result) {
return "bbb";
})
.then(function(result) {
console.log(result);
});
Ответы
Ответ 1
Правило заключается в том, что если функция, которая находится в обработчике then
, возвращает значение, обещание разрешает/отклоняет с этим значением, и если функция возвращает обещание, что произойдет, следующее предложение then
будет быть предложением then
обещания возвращенной функции, поэтому в этом случае первый пример проходит через обычную последовательность thens
и выводит значения, как можно было бы ожидать, во втором примере - объект обещания, который возвращается, когда вы делаете Promise.resolve("bbb")
, а затем then
, который вызывается при цепочке (для всех целей и целей). Способ, которым он фактически работает, описан ниже более подробно.
Цитата из спецификации Promises/A +:
Процедура разрешения обещаний - абстрактная операция, принимающая в качестве вклада обещание и значение, которое мы обозначаем как [[Resolve]](promise, x)
. Если x
является допустимым, он пытается обещать, принимая состояние x
, в предположении, что x ведет себя, по крайней мере, как обещание. В противном случае он выполняет обещание со значением x
.
Эта обработка thenables позволяет реализовать реализацию обещаний, если они выставляют метод Promises/A + -compliant. Он также позволяет реализациям Promises/A + "ассимилировать" несоответствующие реализации с помощью разумных методов.
Ключевая вещь, которую следует отметить здесь, - это строка:
если x
является обещанием, принять его состояние [3.4]
ссылка: https://promisesaplus.com/#point-49
Ответ 2
Оба ваших примера должны вести себя примерно одинаково.
Значение, возвращаемое внутри обработчика then()
, становится значением разрешения обещания, полученного от этого then()
. Если значение, возвращаемое внутри .then
, является обещанием, обещание, возвращенное then()
, "примет состояние" этого обещания и решит/отклонит так же, как это обещание.
В первом примере вы возвращаете "bbb"
в первом обработчике then()
, поэтому "bbb"
передается в следующий обработчик then()
.
Во втором примере вы возвращаете обещание, которое немедленно разрешено с помощью значения "bbb"
, поэтому "bbb"
передается в следующий обработчик then()
. (Promise.resolve()
здесь посторонний).
Результат тот же.
Если вы можете показать нам пример, который действительно демонстрирует различное поведение, мы можем сказать вам, почему это происходит.
Ответ 3
У вас уже есть хороший формальный ответ. Я решил, что должен добавить короткий.
Следующие вещи идентичны с Promises/A + promises:
- Вызов
Promise.resolve
(В вашем случае Angular, который $q.when
)
- Вызов конструктора обещаний и разрешение в его резольвере. В вашем случае
new $q
.
- Возврат значения из обратного вызова
then
.
- Вызов Promise.all по массиву со значением и извлечению этого значения.
Таким образом, для обетования или простого значения X следующие значения:
Promise.resolve(x);
new Promise(function(resolve, reject){ resolve(x); });
Promise.resolve().then(function(){ return x; });
Promise.all([x]).then(function(arr){ return arr[0]; });
И неудивительно, что спецификация promises основана на процедуре разрешения Promise, которая позволяет легко взаимодействовать между библиотеками (например, $q и native promises) и облегчает вашу жизнь. Всякий раз, когда может возникать разрешение обещания, возникает резолюция, создающая общую согласованность.
Ответ 4
Проще говоря, внутри функции обработчика then
:
A) Когда x
- значение (число, строка и т.д.):
-
return x
эквивалентен return Promise.resolve(x)
-
throw x
эквивалентен return Promise.reject(x)
B) Когда x
- это обещание, которое уже установлено (не ожидалось):
-
return x
эквивалентен return Promise.resolve(x)
, если обещание уже разрешено.
-
return x
эквивалентен return Promise.reject(x)
, если Promise уже отклонен.
C) Когда x
- это обещание, которое ожидает:
-
return x
вернет ожидающее обещание, и оно будет оценено на следующем then
.
Подробнее об этом читайте в Promise.prototype.then() docs.