なぜそれはまさに
resolve
約束が正しく
someOtherPromise
を待つ完了しますが、
reject
ではない?次のコードサンプルを実行し、console.logの出力を確認します。 「myPromiseが解決しました」と同様に、「myFailingPromiseが拒否されました」というメッセージが2000ミリ秒後に表示されると予想していました。
let someOtherPromise = (previousPromise) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(previousPromise + ' => someOtherPromise after 2000ms');
resolve('someOtherPromise');
}, 2000);
});
}
let myPromise = () => {
return new Promise((resolve, reject) => {
resolve(someOtherPromise('myPromise'));
});
};
let myFailingPromise = () => {
return new Promise((resolve, reject) => {
reject(someOtherPromise('myFailingPromise'));
});
};
myPromise().then((val) => {
// this is executed after `someOtherPromise` resolves.
console.log('myPromise resolved');
}).catch((err) => {
console.log('myPromise rejected');
});
myFailingPromise().then((val) => {
// this is executed after `someOtherPromise` resolves.
console.log('myFailingPromise resolved');
}).catch((err) => {
console.log('myFailingPromise rejected');
});
someOtherPromise.then(reject)
を使用することで意図した動作を実現できることを知っています2番目の例では、しかし、私の質問は、なぜ
reject
の引数としての約束
resolve
で機能するため、不可能です。
。
回答 3 件
拒否は
reason
のみを受け取ります エラーを強調表示します。別の約束ではありません。同じタイプの別のプロミスでプロミスを解決できますが、最後のプロミスの成功ケースのみが表示されます。この適応された実装を見てください:
const someOtherPromise = new Promise((resolve, _) => { resolve("I am a success"); }); const failingPromise = new Promise((_, reject) => { reject("I failed for a reason"); }); someOtherPromise .then((result) => { console.log("some other promise resolves", result); failingPromise .then((success) => { console.log("never called"); }) .catch((reason) => { console.error("failing promise rejects", reason); }); } ) .catch((error) => { console.error("also never called", error); });
これは
then
です -コールバック地獄につながる他の約束を待つための可能なアプローチ。これが、async/await構文も使用できる理由です。const app = async () => { try { const success1 = await someOtherPromise; // will succeed console.log(success1); const success2 = await failingPromise; // never succceds console.log(success2); // never be reached } catch (e) { return Promise.reject(e); // catches the error of failing promise and rethrows it, redundant but here showcases error handling } } ; app() .then(() => { console.log("never be reached because of failing promise"); }) .catch(console.error);
タイムアウト付きの更新された質問に関して、常に別の約束を待つためにできることは次のとおりです。
const otherPromise = async (willBeSuccesful: boolean) => { console.log("started timer for case", willBeSuccesful); return new Promise((resolve, reject) => { setTimeout(() => { console.log("resolve timer for case", willBeSuccesful); const successValue = "Fnord"; // whatever you want return willBeSuccesful ? resolve(successValue) : reject("this other promise failed because of reasons"); // only provide a reason, not another promise }); }; }; const alwaysWaitForOtherPromiseThenRejectAnyway = async (otherPromise) => { try { const success = await otherPromise; // always waits 2 seconds, not matter console.log("other promises succeeded with value", success); } catch (e) { return Promise.reject(e); // passing through reason, redundant, only to showcase } return Promise.reject("reason why this promise failed"); // only happens after otherPromise was resolved, you could swallow that error and fail here or resolve here as well }; const succeedingPromise = otherPromise(true); const failingPromise = otherPromise(false); alwaysWaitForOtherPromiseThenRejectAnyway(succeedingPromise) .catch((reason) => console.error(reason)); // fail after waiting for success of other promise alwaysWaitForOtherPromiseThenRejectAnyway(failingPromise) .catch((reason) => console.error(reason)); // will fail as soon as otherPromise fails
拒否が発生する前に、常にタイムアウトを待機します。拒否にはさまざまな理由があります。出力は次のようになります。
started timer for case true started timer for case false resolve timer for case true resolve timer for case false other promises succeeded with value Fnord reason why this promise failed this other promise failed because of reasons
関連した質問
- 1行のJavaScriptで作成したBLOBURLを取り消す
- あるモジュールから別のモジュールへのフェッチを使用してGETAPIから取得した応答データをエクスポートする方法
- promise settimeoutのベストプラクティスの「関数」とは何ですか?
- PromiseチェーンのConditional内の非同期呼び出しが進行する前に終了しない
- 'then'と 'catch'が次々と呼び出されます
- バニラJSで非同期/待機を書く方法
- Await内のコードがExpoアプリで実行されていません
- forループが完了するのを待ってから、値を返します
- Javascriptでの非同期プログラミング:Promiseall()が期待どおりに機能しない
- 配列内の各アイテムをフェッチする
約束Aを解決するときに、それを解決する値が約束Bである場合、約束Aは約束Bの状態と一致します。
ただし、約束を拒否する場合は、その理由が約束のように見えるかどうかに関係なく、あなたが唯一の理由を与えます。
あなたがする必要があるのは、
someOtherPromise
で解決することです 両方の場合において。とにかく最初の約束を待って拒否したい場合、これを行うことができます: