3

次のコードでは、意図的にエラーをスローしていますが、Chrome(単にテスト目的で使用)では、キャッチにロールアップしません。エラーを親のスコープにロールアップするにはどうすればよいですか?

try {
  setTimeout(function() {
    console.log("Throwing Error...");
    throw({message:"Ouch!"});
  }, 500);
} catch(e) {
  console.log(e.message);
}

Chromeの返信:

Uncaught #<Object>
  (anonymous function)

これが私が取り組んでいる完全な例です。「ボブ」が必要な場合、(意図的に)タイムアウトします。より堅牢なアプリケーションのエラーシステムを使用して学習者に通知できるように、requirejsエラーをキャッチしたいと思います。

(function() {
try {
  var scriptVersion = "1.0.0.1"
  window.onload = function() {
    var script = document.createElement("script");
    script.type = "text/javascript";
    script.src = "//content.com/pkg/" + scriptVersion + "/require-jquery.js";
    script.async = false;
    script.done = false;
    // OnReadyStateChange for older IE browsers
    script.onload = script.onreadystatechange = function() {
      if(!(this.done) && (!this.readyState || this.readyState == "loaded" || this.readyState == "complete")) {
        this.done = true;
        require.config({
          baseUrl: "//content.com/pkg/" + scriptVersion
        });
        require(["bob"]);
      }
    }
    document.getElementsByTagName("head")[0].appendChild(script);
  }
} catch(e) {
  console.log(e);
}
})();
4

4 に答える 4

6

requireJSの実際の問題を解決する方法については、以下の編集を参照してください。

問題は、setTimeout()関数が親のスコープで実行され、エラーなしで完了することです。将来のコールバックイベントを(システムで)スケジュールしますが、そのコールバックが将来発生すると、親の実行範囲が終了し、新しいシステムイベント(クリックなど)のように、トップレベルのシステムからコールバックが開始されます。イベントハンドラ)。

内の無名関数はこれらの変数を参照できるため、親クロージャはまだ存在しsetTimeout()ますが、親スコープの実際の実行が行われるため、try/catchのスコープが実行されます。

匿名関数の実行コンテキストsetTimeout()はトップレベル(システムによって開始される)であるため、try/catchを配置できる親コンテキストはありません。匿名関数内にtry/catchを配置できますが、そこからスローすると、コールバックと呼ばれるシステムに戻りsetTimeout()ます。

コールバック内で発生する例外を独自のコードでキャッチするには、setTimeout()コールバック内にtry/catchを配置する必要があります。

  setTimeout(function() {
    try {
        console.log("Throwing Error...");
        throw({message:"Ouch!"});
    } catch(e) {
        console.log(e.message);
    }
  }, 500);

(この製造されたテストケースではなく)解決しようとしていることの本当の問題を説明した場合、いくつかの便利なオプションを提供できる可能性があります。


実際に解決しようとしている問題を示したので、今すぐ編集してください。require.jsライブラリは、onErrorメソッドを呼び出すことによってすべてのエラーを開始します。メソッドのデフォルトの実装はonError、例外をスローするものです。独自のハンドラーを割り当ててonError、例外ではなくコールバックでエラーを処理できます。これは正しい道のように聞こえます。

requirejsソースから:

/**
 * Any errors that require explicitly generates will be passed to this
 * function. Intercept/override it if you want custom error handling.
 * @param {Error} err the error object.
 */
req.onError = function (err) {
    throw err;
};
于 2012-04-26T16:08:11.740 に答える
1

ブロックthrow後しばらくしてcatch、ブラウザがsetTimeoutコールバックを呼び出したときに発生します。

catch字句スコープではなく、論理スコープを使用します)

于 2012-04-26T16:04:16.497 に答える
1

前の回答者はそれを正しく説明しました。

それについての別の考え方は、setTimeoutが正常に完了し、最初に実行されたときにスローおよび例外が発生しないため、機能していないということです。その後、try-catchブロック内にいなくなったときに実行されます。

次のようにsetTimeout関数内にtrycatchを配置すると機能します。

  setTimeout(function() {
     try {
         console.log("Throwing Error...");
         throw({message:"Ouch!"});
     } catch(e) {
       console.log(e.message);
     }
      }, 500);

それでも質問がある場合はお知らせください。

于 2012-04-26T16:11:16.423 に答える
1

このようなラッパー関数を使用します。

// wrapper function
var tryable = function(closure, catchCallback) {
    closure(function(callback) {
        return function() {
            try {
                callback();
            } catch(e) {
                catchCallback(e);
            }
        };
    });
};


function throwException() {
    throw new Error("Hi");
}
tryable(function(catchable) {
    setTimeout(catchable(throwException), 1000);
}, function(e) {
    console.log("Error:)", e);
});
于 2015-03-09T07:49:40.373 に答える