2013-06-25 12 views
5

jQueryでは、ajaxコールバック・メソッドを間違えた場合、適切なコンソール・エラー・メッセージとスタック・トレースが取得されます。Dojo - 約束を飲み込んだReferenceError例外

$.get("https://api.github.com/users/octocat/orgs", function() { 
    var a = FAIL; 
}); 

しかし、道場/リクエスト/ XHRを使っ道場では、これらのダムのミスを完全に飲み込まれているようです。これを実行するときの私のコンソールの唯一のことは、 "then"と "always"です。

require(["dojo/request/xhr" ], function(xhr) { 
    var promise = xhr.get("https://api.github.com/users/octocat/orgs"); 
    promise.then(function(data) { 
     console.log('then'); 
     var a = FAIL; 
     console.log('goodbye'); 
    }, function() { 
     console.log('error'); 
    }); 
    promise.otherwise(function() { 
     console.log('otherwise'); 
    }); 
    promise.always(function() { 
     console.log('always'); 
    }); 
}); 

廃止予定のdojo.xhrGetを使用すると、問題はほんの少し改善されます。私は、コンソールエラーメッセージを取得し、私のエラーハンドラが呼び出されますが、それは唯一の「にReferenceErrorを{}」と言うと、私が所有する機能を指すことはありませんスタックトレースを私に提供しています。私たちが作るプログラムを書くとき

dojo.xhrGet({ 
    url: "https://api.github.com/users/octocat/orgs", 
    load: function() { 
     console.log('dojo.xhrGet.load'); 
     var a = FAIL; 

     console.log('goodbye dojo.xhrGet.load'); 
    }, 
    error: function() { 
     console.log('dojo.xhrGet.error'); 
    }, 
    handle: function() { 
     console.log('dojo.xhrGet.handle'); 
    } 
}); 

間違いを犯すと、クローム開発ツールのようなツールがあり、それらの間違いを指摘してくれてうれしいです。スタックトレースとエラーメッセージが表示されたときにエラーを検出するまでにかかる時間は、フィードバックが得られない場合よりもはるかに迅速です。私は道場にはフィードバックがありません。そのような人気のある図書館がこのように動作することは信じられません。私は間違って何をしていますか?

答えて

4

あなたはjQueryのから継承された約束の理解は他の皆とは根本的に異なる(/約束をチェック+実装)があります。この回答の残りの部分については、約束/遵守約束について話します。 DojoのDeferredは実際に+準拠ではありませんが、私がここで議論しているすべてのものが同等に適用されます。

約束は不変です。thenを呼び出して約束の状態を変更することはできません。約束は最終的な価値を表しています。「価値が準備できたら、これを行う」と言って約束を変えることは無意味です。

これで、エラーハンドラが呼び出されない理由が説明されていますが、エラーをキャッチするという基本的な考え方はまだ完全に可能です。戻り値を使用するだけです。お約束の上にthenと呼ぶと、それは新しい(ほとんどいつでも)異なる約束を返します。この新しい約束は、オリジナルが解決され、渡された成功ハンドラが呼び出され、何かが返され、何かが2番目の約束の解決価値になる場合、非常に特別です。

同様に、(最初の約束で)エラーハンドラがトリガされ、その関数が何かを返す場合、何かが2番目の約束の解決値になります。スローされたエラーに対しても同じことが言えます。エラーハンドラに渡されます(2番目の約束!)。

は、だからここより約束/ A +のように書かれて、あなたの最初のコードサンプルです:

require(["dojo/request/xhr" ], function(xhr) { 
    var promise = xhr.get("https://api.github.com/users/octocat/orgs"); 
    promise.then(function(data) { 
     console.log('then'); 
     var a = FAIL; 
     console.log('goodbye'); 
    }, function() { 
     console.log('error'); 
    }).then(null, function() { 
     console.log('otherwise'); 
    }); 

    promise.always(function() { 
     console.log('always'); 
    }); 
}); 

は、私は本当にあなたが常に機能して何をしたいのか理解していないので、私はどこに確認されませんでしたそれを置く。コールスタックについては、非同期呼び出しスタックのサポートが非常に進んだQ promiseライブラリをチェックすることをお勧めします。

+0

これは何が起こっているかの素晴らしい説明です。スタックトレースを与えるコードに少し変更があります:http://jsfiddle.net/5rHM6/残念ながら、スタックトレースは正しい行を指していません(これはconsole.error行を指しています)。したがって、エラーをキャッチする場合は、これが正解です。エラーを見つけたい場合は、私の答えを選ぶ傾向があります。しかし、もしあなたがエラーをキャッチすれば、計装は抑止され、あなたは両方の世界の最高を得ることができないようです。 –

+0

あなたはそうです、それは、スタックトレースでサービスを投げる完全なエラーとは対照的に、メッセージを渡すサービス( "エラーがありました")です。私はQライブラリをチェックアウトすることを強く勧めます。これは私が知っている最高の非同期ライブラリであり、確かにこの問題に対処しています。 –

4

dojoConfigでuseDeferredInstrumentation:trueを設定します。ここにはan exampleがあります。

 <script> 
      var dojoConfig = { 
       useDeferredInstrumentation: true 
      }; 
     </script> 
     <script src="js/lib/dojo/dojo.js.uncompressed.js"></script> 

これはconsole.errorにかなりの機能のエラーメッセージとスタックトレース出力を提供します:

ReferenceError {} "ReferenceError: FAIL is not defined 
    at http://fiddle.jshell.net/gNdCb/2/show/:25:17 
    at signalListener (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14205:21) 
    at signalWaiting (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14196:4) 
    at resolve (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14360:5) 
    at signalDeferred (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14249:15) 
    at signalListener (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14220:6) 
    at signalWaiting (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14196:4) 
    at resolve (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14360:5) 
    at signalDeferred (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14249:15) 
    at signalListener (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14226:4) 
    ---------------------------------------- 
    rejected at signalDeferred (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14252:15) 
    at signalListener (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14223:5) 
    at signalWaiting (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14196:4) 
    at resolve (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14360:5) 
    at signalDeferred (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14249:15) 
    at signalListener (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14220:6) 
    at signalWaiting (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14196:4) 
    at resolve (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14360:5) 
    at signalDeferred (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14249:15) 
    at signalListener (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14226:4) 
    ---------------------------------------- 
Error 
    at Promise.then.promise.then (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:14420:24) 
    at http://fiddle.jshell.net/gNdCb/2/show/:23:13 
    at runFactory (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:1117:43) 
    at execModule (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:1245:5) 
    at http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:812:7 
    at guardCheckComplete (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:1260:5) 
    at contextRequire (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:811:6) 
    at req (http://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojo/dojo.js.uncompressed.js:137:11) 
    at http://fiddle.jshell.net/gNdCb/2/show/:21:1" 
+0

もちろん、window.onerrorのようなものでこれらのエラーを実際に捕まえるか処理できるのはいいですね。助言がありますか? –

+0

エラーをキャッチする@David McMullinの答えを参照してください –

0

私は非常に具体的なニーズがありました。が必要です。ブラウザで実装されているネイティブcatch節にヒットする例外はありません。私はこれを必要に応じて、しかし、私はこのようなものを使用する理由ネヴァーマインド:のsetTimeoutを使用することにより

var promise = xhr.get("https://api.github.com/users/octocat/orgs"); 
promise.then(scream(function(data) { 
    //do stuff 
})); 

にそれを使用するために、次に

function scream(func) { 
    return function() { 
     var args = arguments; 
     setTimeout(function(){ 
      func.apply(null, args); 
     }, 0); 
    }; 
} 

を、あなたはそれが不可能のために作る、ブラウザのイベントキューに関数を実行しますあなたの例外を飲み込む道です。ので、しかし、一般的にこれは悪いソリューションです:

  • それはスタックトレースの一部を変更することが
  • をプログラムの動作を変更することができます以前は、同期に非同期に実行コードの一部を、変更
  • ます複数の.then()オブジェクトを返り値に連鎖させることはできません。これは、約束についての本当に素晴らしいことの一つです。

とにかく、私はオプションとして提示しています。

関連する問題