В чем разница между:
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 "bbb";
})
.then(function(result) {
console.log(result);
});Правило заключается в том, что если функция, которая находится в обработчике 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]
Оба ваших примера должны вести себя примерно одинаково.
Значение, возвращаемое внутри обработчика then(), становится значением разрешения обещания, полученного от этого then(). Если значение, возвращаемое внутри .then, является обещанием, обещание, возвращенное then(), "примет состояние" этого обещания и решит/отклонит так же, как это обещание.
В первом примере вы возвращаете "bbb" в первом обработчике then(), поэтому "bbb" передается в следующий обработчик then().
Во втором примере вы возвращаете обещание, которое немедленно разрешено с помощью значения "bbb", поэтому "bbb" передается в следующий обработчик then(). (Promise.resolve() здесь посторонний).
Результат тот же.
Если вы можете показать нам пример, который действительно демонстрирует различное поведение, мы можем сказать вам, почему это происходит.
У вас уже есть хороший формальный ответ. Я решил, что должен добавить короткий.
Следующие вещи идентичны с Promises/A + promises:
Promise.resolve (В вашем случае Angular, который $q.when)new $q.then.Таким образом, для обетования или простого значения 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) и облегчает вашу жизнь. Всякий раз, когда может возникать разрешение обещания, возникает резолюция, создающая общую согласованность.
Проще говоря, внутри функции обработчика 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.