4

サードパーティのライブラリを使用しています。domainエラー処理にノードを使用しています。そのサードパーティのライブラリに渡されたコールバック関数にエラーがある場合、コールバックを複数回呼び出すことになります。

コード例は次のとおりです。

var startFunction = function (callback) {
  //Call thirdParty function and wait for response
  thirdPartyFunction(function (error, data) {
    console.log("Called with");
    console.log(arguments);
    //Assume there is an error in my callback function
    setTimeout(function () {
      dd
      callback.apply(null);
    }, 2000);
  });
}
 //ThirdParty function don't modify anything here
var thirdPartyFunction = function (callback) {
  var Domain = require("domain");
  var d = require('domain').create();
  d.on('error', function (er) {
    console.log("hi");
    callback.apply(null, er);
  });
  d.run(function () {
    setTimeout(function () {
      callback.apply(null, [null, "Hello"]);
    }, 1000);
  });
};
startFunction(function () {
  console.log("Got response")
});

このバグをサードパーティの lib に報告し、ソース コードを変更しました。お気に入り:

d.on('error', function (er) {
  if (isCalled == false) {
    isCalled = true;
  } else {
    return;
  }
  console.log("hi");
  callback.apply(null, er);
});

関数が複数回呼び出される問題が解決されました。しかし、最終的なコールバックが呼び出されることはありません。

node のこの動作を処理するには?

サードパーティの lib にコードを変更すると、アプリケーションがクラッシュします。ラッパードメインを置くことも役に立ちません。

d.on('error', function (er) {
  if (isCalled == false) {
    isCalled = true;
  } else {
    throw new Error("Getting called");
    return;
  }
  console.log("hi");
  callback.apply(null, er);
});

node でそのような場合を処理する最良の方法は何ですか?

4

1 に答える 1

1

次のように、独自のドメイン リスナーをコールバック関数にアタッチできます。

    var startFunction = function (callback) {
  //Call thirdParty function and wait for response
  thirdPartyFunction(function (error, data) {
    var d1 = require('domain').create();
    d1.on('error', function(er){
      console.log("bye");
      callback.apply(null, er);
    });
    d1.run(function () {
      console.log("Called with");
      console.log(arguments);
      //Assume there is an error in my callback function
      setTimeout(function () {
        dd
        callback.apply(null);
      }, 2000);
  });
    })
}

このようにして、エラーが発生した場合、ハンドラーによってキャッチされ、エラーはメイン レベルに戻され、無限ループに巻き込まれることはありません。

于 2013-09-17T20:02:18.393 に答える