0

Ajax コールバックでコールバックからのスローをキャッチするのに問題があります。ここで最小限のテスト ケースを作成しました(以下のコード)。

関数で、init()クラスの新しいオブジェクトを作成し、http://www.jvanderspek.comResourceLoaderを取得しようとします。$.ajax経由。これは成功し、関数が呼び出されます。引数のために、そこでエラーをスローし、関数内の呼び出しツリーの上部でそれをキャッチしたいと思いますが、残念ながら、スローはキャッチされません。これはおそらく、別のスレッドで実行されている Ajax と、実行が既に try ブロックの外にあるときにスローが呼び出されたことに関係していますが、どうすれば修正できますか? おそらく私は原因について誤解していますが、おまけの質問は、なぜこれが起こるのかということです.ResourceLoader.prototype.onDoneinit();

<html>
  <head>
    <title>testbed</title>
    <script src="http://code.jquery.com/jquery-1.8.3.js" type="text/javascript"></script>
  </head>
  <body onload="init();">
  </body>
  <script type="text/javascript">
    init = function() {
      ResourceLoader = function(){}
      ResourceLoader.prototype.load = function(){
        var done = $.proxy(this.onDone, this);
        $.ajax({
          url: "http://www.jvanderspek.com",
        }).done(done);
      }
      ResourceLoader.prototype.onDone = function() {
        console.log( "onDone");
        throw(new Error());
      }
      var rl = new ResourceLoader();
      try {
        rl.load();
      }
      catch(error){
        window.alert( "Error caught" );
      }
    }
  </script>
</html>
4

1 に答える 1

1

これは、Ajax が非同期実行モデルを使用しているためです。

ajax 呼び出しが行われた後の非同期呼び出しでは、コードの実行は、応答が戻ってくるのを待たずに続行されます。サーバーから応答が返ってくると、成功/失敗のコールバックが呼び出されます。

あなたの場合、rl.load();サーバーへのリクエストが送信されるとすぐに(つまり、エラーがスローされる前に)呼び出しが返されるため、catch ブロックが機能していません。

問題の可能な汚い解決策は、追加のパラメーターasync: falseを ajax 呼び出しに渡すことです。ただし、ajax 呼び出しが完了するまでユーザー エクスペリエンスがブロックされるため、Ajax 呼び出しの目的全体に失敗します。私はこのソリューションをテストしていません。おそらくこれを試すことができます。これは誰にもお勧めしませんが、Ajax についての理解の一環として、おそらくこれを試すことができます。

もう 1 つの解決策は、エラー コールバックをメソッドに渡し、そのコールバックでエラーが発生load()した場合に必要なことを行うことです。

元:

init = function() {
    ResourceLoader = function(){}
    ResourceLoader.prototype.load = function(errorCallback){
        var done = $.proxy(this.onDone, this);
        $.ajax({
          url: "http://www.jvanderspek.com",
        }).done(function(){
            try{
                console.log( "onDone");
                throw(new Error());
            }catch(error){
                errorCallback(error)
            }
        });
    }
    var rl = new ResourceLoader();
    rl.load(function(error){
        window.alert( "Error caught" );
    });
}
于 2012-12-22T11:19:51.013 に答える