##他の処理方法との違い
前回のPart1ではforEach + async/awaitを使いましたが、今回はforLoop + async/awaitを使ってテストします。
このforLoop + async/awaitによる処理については、関数processArrayの中のawaitがしっかり効いて、逐次処理(順番に、ひとつ前の処理の結果が出てから次の処理を実行)となります。
また、awaitが効いているため、アウトプットの順番はインプットした順番と同じになりますので、今回はソートする必要はありません。
##ループ処理の内容
基本的にPart1と同じですが、フェイク非同期関数(fakeDatabaseQuery)を作成し、forLoopとasync/awaitを利用して、処理を(1 ~ 100まで)100回実行します。
プログラム内部にも説明がありますが、awaitは受けとる予定のpromiseオブジェクトがfullfilledまたはrejectedとなるまでファンクションの実行をサスペンドしますので、100回のループ処理において、ファンクションを止めている(サスペンドしている)時間がかなりの割合で発生していることになります。
##まとめ
Part1と比較して、フェイク非同期関数をループ実行する点は同じですが、こちらはforEachと違いasync/awaitがしっかり効きます!
ということで、全体としてサスペンドされている時間が長いので、当然ながら「遅い」です。ただし、アルゴリズム上、このような逐次処理をする必要がある場合は、このsyntax(構文)は意味があることになります。
##その他
下記のサンプルコードは、Node.js v14.15.5でテストしたものです。また、私の環境(Ubuntu + Node.js)で実行すると、約5秒かかります。
##サンプルコード
console.time();
let fakeSearchResult = [];
//整数の1~100まで並んでいるarrayを作ります
let arrayN = [];
const arrayLength = 100;
for (let i = 0; i < arrayLength; i++) {
arrayN.push(i+1);
}
//データベース検索を偽装したフェイク非同期関数
function fakeDatabaseQuery(index) {
const elapse = Math.floor(Math.random() * 100);
const promise = new Promise(function(resolve, reject) {
const result = {
index:index,
elapse:elapse
}
setTimeout(() => resolve(result), elapse);
});
return promise;
}
async function processArray(array) {
for (let i = 0; i < array.length; i++) {
//awaitは、受けとる予定のプロミスオブジェクトがfulfilledかrejectedとなるまで、
//このファンクションの動作をサスペンドします
const obj = await fakeDatabaseQuery(array[i]);
console.log('obj', obj);
fakeSearchResult.push(obj);
}
console.log('fakeSearchResult:',fakeSearchResult);
console.timeEnd();
}
processArray(arrayN);