1. ホーム
  2. javascript

javascriptのプロミスをデバッグする方法は?

2023-09-01 05:37:01

質問

私はプロミスに基づいている非同期コードをデバッグする方法を理解しようとしています。約束によって私はECMAScript 6ベースの約束を意味し、デバッグによって私は組み込みのクロムまたはFirefoxのデバッガを使用することを意味します。

私が困っていることは、エラーが発生したとき、私がそれを「拒否」する方法に関係なく、スタックトレースを得ることができないようであることです。

私はこれらを試しました。

console.log(new Error('Error occured'));
throw new Error('Throwing an Error');
return new Error('Error returned by the onRejected function');
reject(new Error('Pass Error to the reject function'));

しかし、これらのどれもコードの実際のエラー、またはスタックトレースを返しません。

そこで私の質問は、JavaScriptのPromiseを適切にデバッグするにはどうしたらいいかということです。

どのように解決するのですか?

これは議論するのに最適なトピックですが、悲しいことに、これはネイティブの約束事で実際にはかなり難しいのです。

Chromeで生のES6プロミスをデバッグするのは恐ろしいことです。なぜなら、それらはエラーを静かに抑制し、キャッチを省略するときはいつでも、プロミスが失敗したことを示すいかなる表示も与えないからです。 更新: Chrome は処理されない拒否をログに記録するようになりました。 を記録するようになりました (方法についてはこのリンクを参照してください)。

 Promise.resolve("foo").then(function(){
      throw new Error("You will never see this");// silent failure
 });

Firefox では、未処理の拒絶を検出するようになったので、少し良くなりました。しかし、まだ不安定で、プロミスをどこかに代入するとうまくいきません。

では、どうすればよいのでしょうか。

以下を含む ブルーバード - はES6プロミスのスーパーセットで、内部ですぐに交換でき、よりリッチなAPIを持ち、より速く、そして 驚くべきスタックトレース . デバッグを念頭に置いて構築されており、素晴らしいエラー処理機能を備えています。

Bluebirdを入れたら、呼び出し。

Promise.longStackTraces();

これは少し速度を落とし(それでも非常に速いのですが)、驚くべきエラーメッセージを表示します。例えば

Promise.resolve().then(function outer() {
    return Promise.resolve().then(function inner() {
        return Promise.resolve().then(function evenMoreInner() {
            a.b.c.d()
        });
    });
});

ネイティブのプロミスでは、これはサイレントエラーとなり、デバッグが非常に困難になります。Bluebirdのプロミスでは、デフォルトでコンソールに大きな赤いエラーが表示されます。

ReferenceError: a is not defined
    at evenMoreInner (<anonymous>:6:13)
From previous event:
    at inner (<anonymous>:5:24)
From previous event:
    at outer (<anonymous>:4:20)
From previous event:
    at <anonymous>:3:9
    at Object.InjectedScript._evaluateOn (<anonymous>:581:39)
    at Object.InjectedScript._evaluateAndWrap (<anonymous>:540:52)
    at Object.InjectedScript.evaluate (<anonymous>:459:21)

デバッグが終わったら、それをスワップしてネイティブのプロミスに戻すことができます。個人的には、本番でエラーがあることを知ることに価値があるので、それはお勧めしませんが、確かにそれは可能です。