Promiseを使用すると、ブラウザが拒否を2回返すのに、解決を2回返さないのはなぜですか?


10

javaScriptを理解できませんpromises。次のコードを書きました。

var p = new Promise(function(resolve,reject){

    reject(Error("hello world"));
});

setTimeout(()=>p.catch(e=>console.log(e)),5000);

これはChromeデベロッパーコンソールにすぐに表示されます。 ここに画像の説明を入力してください

しかし、5秒待った後、メッセージは次の画像のように自動的に黒に変わります。 ここに画像の説明を入力してください

私のjavaScriptコードと開発者コンソールの間でこの動作を見たことはありません。私のJavaScriptスクリプトは、開発者コンソールで「既存のコンテンツを変更」できます。

そこで、resolve次のコードを記述して、同じ状況が発生するかどうかを確認することにしました。

var p = new Promise(function(resolve,reject){

    resolve("hello world");
});

setTimeout(()=>p.then(e=>console.log(e)),5000);

しかし、この状況では、私の開発者コンソールには5秒後まで何も表示されず、そこに出力されhello worldます。

とが呼び出されるタイミングの点でresolveとのreject扱いが異なるのはなぜですか?


追加

私もこのコードを書きました:

var p = new Promise(function(resolve,reject){

    reject(Error("hello world"));
});

setTimeout(()=>p.catch(e=>console.log("errors",e)),5000);
setTimeout(()=>p.catch(e=>console.log("errors 2",e)),6000);
setTimeout(()=>p.catch(null),7000);

これにより、開発者コンソールにいくつかの出力が発生します。時間0で赤のエラー、時間5秒でテキストに赤が黒に変わりerrors hello world、時間6秒で新しいerrors 2 hello worldエラーメッセージ、時間7秒で赤のエラーメッセージ。今私はreject実際に何回呼び出されるのか非常に混乱しています...私は迷子になっています...


1
ただ脇に:var p = new Promise(function(resolve,reject){ reject(Error("hello world")); });より慣用的かつ簡潔に次のように書くことができますvar p = Promise.reject(Error("hello world"));:-)
TJクラウダー

1
素晴らしい質問です。
TJクラウダー、

回答:


11

うわー、それは本当にクールです。コンソールがこれを行うのを見たことがない。(ただし、他の形式の動的動作があるので、...)これが起こっていることです:

最初のケースでは、setTimeoutコールバックのコードの外側にあるすべてのコード実行が完了し、実行スタックが返されるため、(現時点では)ユーザーランドJavaScriptコードではなく、「プラットフォームコード」(Promises / A +仕様で呼び出される)のみが実行されます。その時点で、promiseは拒否され、何も拒否を処理していないため、未処理の拒否であり、devtoolsはそれを報告します。

次に、5秒後、コールバックが実行され、拒否ハンドラがアタッチされます。この時点で、拒否は処理されなくなりました。どうやら、Chrome / V8 / devtoolsは連携して、コンソールから未処理の拒否の警告を削除します。代わりに表示されるのは、を介して拒否ハンドラに出力したものですconsole.log。拒否ハンドラをより早くアタッチした場合、その未処理の拒否エラーは発生しません。

フルフィルメントを処理しないことはエラー状態ではないため、フルフィルメントではこれは起こりません。拒否の扱いはありません。


1
ああ、それは理にかなっています。FireFoxが少し異なる方法で処理することに気づきました。しかし、わかりました、今はもっと理にかなっています。
John

1
私も同じように書いて答えましたが、SOをロードしたので、投稿していません。いい説明だ!+1
FZは
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.