マイナー・マイナー

隠れた名作の発掘が生きがい。

【Node.js】Promiseを利用してAPIを並列に呼び出す


スポンサードリンク

あるAPIを並列に呼び出し、
1. APIへのリクエストがすべて成功したらSuccess
2. APIへのリクエストがひとつでも失敗したらFailure
する、そんなプログラムを書きました。Node.jsとPromiseで実装しました。

サンプルコード

クライアント側

あるAPIのURLに対してGETでリクエストし、そのStatusCodeが200ならば成功(Success)、それ以外であれば失敗(Failure)を出力するプログラムです。


PromiseでAPIを呼び出したい数分のタスクを作成し、Promise.Allで並列に実行させます。タスクの中でAPIのStatusCodeが200ならばresolve()、それ以外であればreject()を呼び出します。全てresolveであれば、thenの中が実行され、一つでもrejectがあればcatchの中が実行されます。

promise-test.js

var request = require('request');

var REQUEST_COUNT = 5;
var apiUrl = "http://127.0.0.1:1338/";
var taskArray = [];

// タスク作成
for (var i = 0; i < REQUEST_COUNT; i++) {
    var task = new Promise(function(resolve, reject) {
        // リクエストデータ作成
        var param = {
            'data' : i,
        };

        var options = {
            uri : apiUrl,
            method : 'GET',
            headers : {
                'Content-Type' : 'application/x-www-form-urlencoded',
            },
            form : param
        };

        // リクエストデータ
        request.post(options, function(error, response, body) {
            if (!error && response.statusCode == 200) {
                resolve();
            } else {
                reject();
            }
        });
    });
    taskArray.push(task);
}

// タスク実行
Promise.all(taskArray).then(function() {
    console.log("Success");
}).catch(function () {
    console.log('Failure');
});

サーバ側

10回に1回は失敗する(statusCode!=200)サーバを実装しました。

promise-test-server.js

var http = require('http');

http.createServer(function(req, res) {
    console.log("-----------");
    // リクエストデータの確認
    var data = '';
    req.on('readable', function(chunk) {
        data += req.read();
    });
    req.on('end', function() {
        console.log(data);
    });

    var statusCode;
    // ランダムに失敗させる
    var x = Math.random();
    if(x < 0.9){
        statusCode = 200;
    }else{
        statusCode = 400;
    }
    console.log("statusCode:" + statusCode);

    // Response
    res.writeHead(statusCode, {
        'Content-Type' : 'application/json',
    });
    res.end();

}).listen(1338, '127.0.0.1');

処理結果

すべてのリクエストが成功する場合

クライアントログ

Success


サーバログ

-----------
statusCode:200
data=0
-----------
statusCode:200
data=1
-----------
statusCode:200
data=2
-----------
statusCode:200
data=3
-----------
statusCode:200
data=4

ひとつでもリクエストが失敗する場合

クライアントログ

Failure


サーバログ

-----------
statusCode:200
data=0
-----------
statusCode:200
data=1
-----------
statusCode:200
data=2
-----------
statusCode:200
data=3
-----------
statusCode:423
data=4