2015年5月15日金曜日

[Node.js] 複数のHTTPリクエストを同期的に行うサンプル

nodejsで複数のHTTPリクエストを投げる際、それらの複数のHTTPリクエストを投げっぱなしではなく、順番に(つまり同期的に)処理したいときもあると思います。以下のサンプルコードでは setTimeout() を使ってそれを実現しています。

まずはnodejsアプリの下準備をしておきます。

package.json
{
  "name": "intervallic-multi-requests-example",
  "description": "Intervallic Multiple HTTP requests example",
  "version": "0.0.1",
  "engines": {
    "node": ">=0.8.0"
  },
  "dependencies": {
    "request": "^2.55.0"
  }
}

今回はHTTPリクエストに request モジュールを使います。
npmでインストールしておきましょう。

$ sudo npm install --save request

ではアプリ本体です。

app.js
var request = require('request');

var urls = [
  'http://www.google.com',
  'http://DUMMY_HOST',
  'https://www.bing.com',
  'http://www.yahoo.com',
  "http://stackoverflow.com",
  "http://github.com",
  "http://www.yahoo.co.jp"
];

function execRequests(urls, callback) {

  var url;
  var length = urls.length;

  function execRequest(idx) {
    url = urls[idx];
    console.log("executing execRequest()... url:", url);
    // exec http request
    request(url, function(error, response, body) {
      if (!error && response.statusCode == 200) {
        console.log("  url:", url, "statusCode:", response.statusCode);
      } else if (error) {
        console.log("  error.code:", error.code);
      }
      // sleep or return
      if (idx + 1 < length) {
        console.log("  execute execRequest() after 1000ms...");
        // execute the recursive function "execRequest()" after 1000 ms
        setTimeout(function() {
          execRequest(idx + 1)
        }, 1000);
      } else {
        return callback();
      }
    });
  }

  // fire the recursive function "execRequest()"
  execRequest(0);
}

execRequests(urls, function() {
  console.log("End.");
});

URL配列のindexを保持しておき、setTimeout()でexecRequest(index)を再帰呼出しすることで複数のHTTPリクエストの同期処理を実現しています。

実行

$ node app.js
executing execRequest()... url: http://www.google.com
  url: http://www.google.com statusCode: 200
  execute execRequest() after 1000ms...
executing execRequest()... url: http://DUMMY_HOST
  error.code: ENOTFOUND
  execute execRequest() after 1000ms...
executing execRequest()... url: https://www.bing.com
  url: https://www.bing.com statusCode: 200
  execute execRequest() after 1000ms...
executing execRequest()... url: http://www.yahoo.com
  url: http://www.yahoo.com statusCode: 200
  execute execRequest() after 1000ms...
executing execRequest()... url: http://stackoverflow.com
  url: http://stackoverflow.com statusCode: 200
  execute execRequest() after 1000ms...
executing execRequest()... url: http://github.com
  url: http://github.com statusCode: 200
  execute execRequest() after 1000ms...
executing execRequest()... url: http://www.yahoo.co.jp
  url: http://www.yahoo.co.jp statusCode: 200
End.

ちゃんと順番に実行されていますね。

0 件のコメント:

コメントを投稿