1. ホーム
  2. javascript

[解決済み] Node.jsで非同期関数の長いネストを回避する方法

2022-04-25 01:11:19

質問

DBからデータを表示するページを作りたいので、DBからデータを取得する関数をいくつか作りました。私はNode.jsの初心者なので、私が理解する限りでは、1つのページ(HTTP応答)でそれらをすべて使用したい場合、それらをすべてネストする必要があります。

http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/html'});
  var html = "<h1>Demo page</h1>";
  getSomeDate(client, function(someData) {
    html += "<p>"+ someData +"</p>";
    getSomeOtherDate(client, function(someOtherData) {
      html += "<p>"+ someOtherData +"</p>";
      getMoreData(client, function(moreData) {
        html += "<p>"+ moreData +"</p>";
        res.write(html);
        res.end();
      });
    });
  });

そのような関数がたくさんある場合 ネストが問題になる .

これを避ける方法はあるのでしょうか?複数の非同期関数をどう組み合わせるかに関係するのでしょうが、何か基本的なことのような気がします。

解決方法は?

興味深い観察があります。JavaScriptでは通常、インラインの匿名コールバック関数を名前付き関数変数で置き換えることができることに注意してください。

次のようなものです。

http.createServer(function (req, res) {
   // inline callback function ...

   getSomeData(client, function (someData) {
      // another inline callback function ...

      getMoreData(client, function(moreData) {
         // one more inline callback function ...
      });
   });

   // etc ...
});

このように書き換えることができます。

var moreDataParser = function (moreData) {
   // date parsing logic
};

var someDataParser = function (someData) {
   // some data parsing logic

   getMoreData(client, moreDataParser);
};

var createServerCallback = function (req, res) {
   // create server logic

   getSomeData(client, someDataParser);

   // etc ...
};

http.createServer(createServerCallback);

しかし、コールバック・ロジックを他の場所で再利用する予定がない限り、この例のようにインラインの無名関数の方がはるかに読みやすい場合が多いのです。また、すべてのコールバックの名前を探す手間が省けます。

さらに を使用します。 のコメントで指摘されているように、内部関数内でクロージャ変数にアクセスしている場合、上記は素直な翻訳とは言えません。そのような場合は、インラインの無名関数を使うのがより望ましい。