私はbluebirdを使用していますが、同期関数をPromiseに解決する方法は2つありますが、両方の方法に違いはありません。スタックトレースは少し異なるように見えるので、それらはalias
だけではありませんよね?
それでは、好ましい方法は何ですか?
ウェイA
function someFunction(someObject) {
return new Promise(function(resolve) {
someObject.resolved = true;
resolve(someObject);
});
}
ウェイB
function someFunction(someObject) {
someObject.resolved = true;
return Promise.resolve(someObject);
}
コメントの両方の答えに反して、違いがあります。
ながら
Promise.resolve(x);
基本的にと同じです
new Promise(function(r){ r(x); });
微妙なところがあります。
通常、Promiseを返す関数は、非同期でスローする可能性があるため、同期でスローしないことを保証する必要があります。予期しない結果と競合状態を防ぐために、スローは通常、返された拒否に変換されます。
これを念頭に置いて-仕様が作成されたとき、promiseコンストラクターは安全にスローされます。
someObject
がundefined
である場合はどうなりますか?Bluebirdはこれを見て、PetkaがPromise.method
を追加してこの問題に対処し、戻り値を使い続けることができるようにしました。したがって、これをBluebirdで記述する最も簡単で正しい方法は、実際はどちらでもありません。
var someFunction = Promise.method(function someFunction(someObject){
someObject.resolved = true;
return someObject;
});
Promise.methodは、スローを拒否に変換し、解決に戻ります。これは最も安全な方法であり、戻り値を通じてthen
ablesを同化するので、someObject
が実際に約束そのものであっても機能します。
一般に、Promise.resolve
は、オブジェクトと外部プロミス(thenables)をプロミスにキャストするために使用されます。それがユースケースです。
上記の回答やコメントで言及されていない別の違いがあります。
someObject
が保留中のPromise
である場合、new Promise(resolve)
は1ティック追加されます。
次の2つのコードスニペットを比較します。
_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");
});
_
2番目のスニペットは、最初に 'tick 3'を出力します。どうして?
値がプロミスの場合、Promise.resolve(value)
は正確に値を返します。 Promise.resolve(value) === value
はtrueになります。 [〜#〜] mdn [〜#〜] を参照してください
しかし、new Promise(resolve => resolve(value))
は、value
promiseに追従するためにロックされた新しいpromiseを返します。 「ロックイン」を行うには、追加の1ティックが必要です。
_// 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
_呼び出しが最初に実行されます。
参照: