asyncは、node.js でよく使用される一般的な非同期フロー制御ライブラリです。私はブラウザで個人的に使用したことはありませんが、ブラウザでも動作するようです。
この例では、(理論的には) 2 つの関数を実行し、すべてのファイル名とその読み込みステータスのオブジェクトを返します。 async.map
は並行して実行されますwaterfall
が、 はシリーズであり、各ステップの結果を次のステップに渡します。
ここでは、2 つの非同期関数がコールバックを受け入れると想定しています。そうでない場合は、それらがどのように使用されることを意図しているかについて、より多くの情報が必要です (完了時にイベントを発生させますか? など)。
async.waterfall([
function (done) {
fetchFiles(source, function(list) {
if (!list) done('failed to fetch file list');
else done(null, list);
});
// alternatively you could simply fetchFiles(source, done) here, and handle
// the null result in the next function.
},
function (file_list, done) {
var loadHandler = function (memo, file, cb) {
loadFile(file, function(data) {
if (!data) {
display('failed to load: ' + file);
} else {
display(data);
}
// if any of the callbacks to `map` returned an error, it would halt
// execution and pass that error to the final callback. So we don't pass
// an error here, but rather a tuple of the file and load result.
cb(null, [file, !!data]);
});
};
async.map(file_list, loadHandler, done);
}
], function(err, result) {
if (err) return display(err);
// All files loaded! (or failed to load)
// result would be an array of tuples like [[file, bool file loaded?], ...]
});
waterfall
関数の配列を受け入れて順番に実行し、それぞれの結果を引数として次の引数として渡し、最後の引数としてコールバック関数を渡します。これは、エラーまたは関数からの結果データで呼び出します。
もちろん、コードの構造をまったく変更することなく、これら 2 つの間または前後に任意の数の異なる非同期コールバックを追加できます。 waterfall
は実際には 10 の異なるフロー制御構造のうちの 1 つにすぎないため、多くのオプションがあります (ただし、ほとんどの場合、最終的に を使用auto
することになりますが、これにより、Makefile のような要件構文を介して同じ関数で並列実行と直列実行を混在させることができます)。