Node.jsでasync.forEachSeriesとasync.waterfallを組み合わせて使う方法

asyncのforEachSeriesとwaterfallを組み合わせて使っているパターンがなかったのでまとめてみました。

イメージとしては親となるデータをリストで取得して、関連する子のリストを取得・削除を複数行うイメージです。

async.forEachSeries(data.Items, function (item, callback2) {
    async.waterfall([
        //delete 1
        function (callback) {
            select(item.Name, 'target1', function (err, data) {
                callback(err, data);
            });
        }, function (val, callback) {
            delete(val, 'target1', function (err, data) {
                callback(err);
            });
        },
        //delete 2
        function (callback) {
            select(item.Name, 'target2', function (err, data) {
                callback(err, data);
            });
        }, function (val, callback) {
            delete(val, 'target2', function (err, data) {
                callback(err, item.Name);
            });
        }
    ], function (err2, results) {
        callback2();
    });
}, function (err3) {
    console.log('all done!');
});

async.forEachにしてしまうと、複数のdata.Itemsに対して最初のselect→deleteのように並列して処理するような感じになるので、1つのdata.Itemに対して1個流しでやる場合にはasync.forEachSeriesの方がわかりやすいです。

async.waterfallでは値を次の関数に渡せるのがメリットですが、その際に変なのを渡すと途中でこけるので注意が必要です。