16

問題

JSFiddle : http://jsfiddle.net/missingno/Gz8Pe/2/

次のようなコードがあります。

var d = new Deferred();
d.resolve(17);
return d.then(function(){
     //do some stuff...
})
.then(function(){
    var obj = a_funtion_that_returns_null_on_IE();
    var x = obj.some_property; //BOOM!
});

問題は、私が IE を使用しているとき、対応する行番号への参照がなく、デバッガーが問題のある行で停止することなく、'obj' is null or not an objectエラーしか表示されないことです (私が望むように)。

この種の問題は、コードをデバッグするのが面倒であり、私が今考えることができる唯一の解決策 (制御フロー ライブラリをいじるか、デバッガーまたは console.log を使用した段階的なデバッグに頼る) は、私が考えることです。むしろしなくていい。

何が起こっていると思いますか

チェーンが起動された後にエラーバックを追加できるようにするためにthen、コールバックによってスローされた例外を事前にキャッチします。これが、IE デバッガーがエラーで停止しないか、行番号を含む通常のエラー メッセージを表示する理由だと思います。

行番号のないエラー メッセージは、制御フロー ライブラリからのものです。これはdeferredOnError、例外がキャッチされて後で使用できるように保存されるたびに呼び出されるフックを提供します。デフォルトの動作は、Error オブジェクトを console.error-ing することです。

dojo.config.deferredOnError = function(err){
    //a chance to log the exception after it is captured by "then"
    //or do other things with it
    console.error(err);
}

悲しいことに、IE のエラー オブジェクトから行番号またはスタック トレースを取得する方法がわかりませんでした。また、例外を再スローしてトップレベルまでバブルアップさせることができない方法でフックが呼び出されました。

私が欲しいもの

非同期コードをデバッグしてから、デバッガーを段階的に使用するより良い方法が必要です。最良の場合、デバッガーを例外で停止させる方法(未処理の例外の場合と同様) 、または少なくとも、スローされた Error オブジェクトから行番号またはスタック トレースを取得する方法。

4

3 に答える 3

14

これは、事前の構成なしで任意のフレームワークで機能し、最近のすべてのブラウザーがこれをサポートしています。

キャッチされた例外で一時停止:これにより、JavaScript の実行が実際に停止し、問題のあるコードが発生している場所に正確に移動します。

キャッチされた例外で一時停止

Chrome の場合:

  1. 開発者ツール,
  2. ソースタブ
  3. 例外で一時停止(停止のようなアイコン) してから
  4. キャッチされた例外で一時停止チェックボックス
于 2014-11-11T19:11:17.697 に答える
4

私がやったこと

非同期ヘルパー関数のミニ ライブラリにシーケンス関数を追加しました。基本的に一連の「then」呼び出しを実行しますが、中間ステップを追加して、最終的に Deferred によってキャッチされる例外を再スローすることを除きます。また、例外をキャッチするオプションのエラー ハンドラーも受け入れます。

私がそれを呼び出すと、次のようになります。

go([
    function(){
        return 17;
    },
    function(x){
        //return some stuff
    },
    function(){
         var obj = a_function_that_returns_null_on_IE();
         var x = obj.some_property; //BOOM!
    }
], function(){
    //an optional error handler
});

このようにしたもう 1 つの理由は、同期コードまたは非同期コードのいずれかと同時に動作する必要があるコードがたくさんあることです (連鎖を行うために Deferred.when を使用します)。カスタム関数を使用すると、単一の統一された構文を使用できるようになり、非同期ケースでキャプチャされないエラーは、Deferred が関与しない同期ケースと一致します。一般的なケースとは異なり、「go」を使用しているときは、どのコードが呼び出されるかをアプリオリに知っているため、エラーをキャプチャしなくても問題ないと思います。そのため、誰かがキャッチする必要がある場合に例外をキャプチャする必要はありません。それらを将来的に。

また、カスタム ソリューションを使用することで、個人的なデザイン設定を自由に適用することができました :)


それに加えて、コード ベース全体で生成する例外の量を減らすことができました。非同期コードで例外を管理するのは通常より面倒で、null またはエラー コードを返すことでエラー条件の処理にフォールバックする方が簡単な場合があります。

また、自分で作成した例外は、他のオブジェクトではなく、組み込みの Error クラスのインスタンスであることを確認しました。その理由は、ビルトインの Error クラスが、一種のクロスブラウザーの方法で生成された場所の行番号とスタック トレースを記録するためです。

于 2012-04-27T18:35:30.243 に答える