0
0

More than 1 year has passed since last update.

非同期関数のループ処理 - Part3(forLoop + 非同期関数内部でthenメソッド使用)

Last updated at Posted at 2021-09-20

他の処理方法との違い

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);

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0