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では値を次の関数に渡せるのがメリットですが、その際に変なのを渡すと途中でこけるので注意が必要です。