Я использую bluebird и вижу два способа преобразовать синхронные функции в Promise, но я не вижу различий между ними. Похоже, трассировка стека немного отличается, так что это не просто, не так ли alias
?
Итак, какой способ предпочтительнее?
Путь А
function someFunction(someObject) {
return new Promise(function(resolve) {
someObject.resolved = true;
resolve(someObject);
});
}
Путь Б
function someFunction(someObject) {
someObject.resolved = true;
return Promise.resolve(someObject);
}
Promise.resolve
это просто сахар.Ответы:
Вопреки обоим ответам в комментариях - разница есть.
Пока
Promise.resolve(x);
в основном то же самое, что
new Promise(function(r){ r(x); });
есть тонкость.
Функции, возвращающие обещание, обычно должны иметь гарантию того, что они не должны вызывать синхронно, поскольку они могут вызывать асинхронно. Чтобы предотвратить неожиданные результаты и условия гонки - броски обычно конвертируются в возвращенные отклонения.
Имея это в виду - когда спецификация была создана, конструктор обещаний безопасен.
Что если
someObject
естьundefined
?Bluebird увидел это, и Petka добавил,
Promise.method
чтобы решить эту проблему, чтобы вы могли продолжать использовать возвращаемые значения. Так что правильный и самый простой способ написать это в Bluebird на самом деле ни то, ни другое - это:var someFunction = Promise.method(function someFunction(someObject){ someObject.resolved = true; return someObject; });
Promise.method преобразует броски в отклоненные и возвращает в решенные за вас. Это наиболее безопасный способ сделать это, и он ассимилирует
then
способности через возвращаемые значения, поэтому он будет работать, даже еслиsomeObject
на самом деле это обещание.Обычно
Promise.resolve
используется для приведения объектов и внешних обещаний (thenables) к обещаниям. Это его вариант использования.источник
Promise.resolve()
- это анти-шаблон?Promise.resolve()
новый экземплярPromise
таким же образом, как и при использованииnew
? Если нет,return Promise.resolve(yourCode)
будет быстрее и избежать синхронных бросков.Promise.coroutine
что еще полезнее.Есть еще одно различие, не упомянутое в приведенных выше ответах или комментариях:
Если
someObject
естьPromise
,new Promise(resolve)
будут стоить два дополнительных тика.Сравните два следующих фрагмента кода:
const p = new Promise(resovle => setTimeout(resovle)); new Promise(resolve => resolve(p)).then(() => { console.log("tick 3"); }); p.then(() => { console.log("tick 1"); }).then(() => { console.log("tick 2"); });
const p = new Promise(resovle => setTimeout(resovle)); Promise.resolve(p).then(() => { console.log("tick 3"); }); p.then(() => { console.log("tick 1"); }).then(() => { console.log("tick 2"); });
Второй фрагмент сначала напечатает «галочку 3». Зачем?
Если значение является обещанием,
Promise.resolve(value)
вернет значение точно.Promise.resolve(value) === value
было бы правдой. см. MDNНо
new Promise(resolve => resolve(value))
вернет новое обещание, которое будет следоватьvalue
обещанию. Для «блокировки» требуется дополнительная галочка.// something like: addToMicroTaskQueue(() => { p.then(() => { /* resolve newly promise */ }) // all subsequent .then on newly promise go on from here .then(() => { console.log("tick 3"); }); });
tick 1
.then
Вызов будет работать в первую очередь.Ссылки:
источник