##他の処理方法との違い
Part1ではforEach + async/await、Part2ではforLoop + async/awaitを使いましたが、今回は、async/awaitなしでforLoopを実行します。ただし、その際にループ処理の対象となる関数fakeDatabaseQuery内部では、promise + thenメソッドを使用します。
Part2との違いは、async/awaitなしでforLoopを回している点、および、フェイク非同期関数内部でpromiseとthenメソッドを使い連続した非同期の処理を行っている点となります。
また、今回はasync/awaitなどの逐次処理を実施する仕組みがなく、アウトプットの順番がランダムになるため、ファンクションarraySorterによって、元の順番に戻しています。
##ループ処理の内容
フェイク非同期関数(fakeDatabaseQuery)を作成し、forLoopでこの非同期関数を100回実行します。
ループ処理によって、promiseオブジェクトが連続的に作成されますが、それぞれのpromiseはresolveされた順番で次の.thenの中のプロセスに渡され、処理されていきます。
ただし、promiseを生成する段階で、わざとsetTimeoutが、Math.random()によって生成されたelapseの値を使って、resolveする際の遅延を作り出していますので、当然、次の.thenの中で実施されるアレイfakeSearchResultに結果を詰め込んでいく作業についても、そのelapseの値に影響を受けて順番がバラバラになります。
##まとめ
今回は、async/awaitなしで、forLoopによりフェイク非同期関数(fakeDatabaseQuery)を実行していますが、そのフェイク非同期関数内部ではpromiseとthenメソッドを使用した処理が行われます。
Part2のようなサスペンドされた状態が生じないため、結果として非常に高速な処理を実現しています。
##その他
下記のサンプルコードは、Node.js v14.15.5でテストしたものです。また、私が利用している環境(Ubuntu + Node.js)では、処理時間は110ms ~ 120msとなりました。
##サンプルコード
console.time();
//整数が1~100まで並んでいるarrayを作ります
let arrayN = [];
const arrayLength = 100;
for (let i = 0; i < arrayLength; i++) {
arrayN[i] = i + 1;
}
let fakeSearchResult = [];
function arraySorter(array){
array.sort(function(a, b) {
return a.index - b.index;
});
}
//fakeDatabaseQuery内部で、プロミスとthenメソッドを利用した連続した非同期の処理を行います。
function fakeDatabaseQuery(item, length) {
//ランダムナンバーにより2桁の整数を生成
const elapse = Math.floor(Math.random() * 100);
const promise = new Promise(function(resolve, reject) {
const obj = {index:item, elapse: elapse};
//setTimeoutを使い、意図的に遅延を作りだしています
setTimeout(() => resolve(obj), elapse);
});
promise.then((obj) => {
fakeSearchResult.push(obj);
let fsrLength = fakeSearchResult.length;
if (fsrLength === length){
console.log('fakeSearchResult-1:',fakeSearchResult);
arraySorter(fakeSearchResult);
console.log('fakeSearchResult-2:',fakeSearchResult);
console.log('Yeah!');
console.timeEnd();
}
})
}
function processArray(array) {
const length = array.length;
for (let i = 0; i < array.length; i++) {
fakeDatabaseQuery(array[i], length);
}
console.log('Donatta?');
}
processArray(arrayN);