使用Promise和async-await實現的一個異步遍歷+同步執行任務的實例

假設我們需要做N個同樣的檢測任務,檢測完成後會將結果存入數據庫。
我們希望每個檢測是同步完成的,完成後再進行儲存。
同時,我們又希望這些任務一起開始執行。
不需要檢查這些任務何時完畢。

/**
 * 檢測一個接口,返回檢測結果
 * @param host
 * @param port
 * @returns {Promise}
 */
function detectOnePromise(host, port) {
    return new Promise((resolve, reject) => {
        let start = new Date().getTime();
        let state = -1;
        console.log(`detecting ${host}:${port} ...`)
        let check = net.connect({host, port}, () => {
            console.log(`${host}:${port} is openning`);
            state = 0;
            try {
                check.destroy();
            } catch (e) {
                throw e;
            }
        });

        setTimeout(() => {
            console.log(`detect ${host}:${port} timeout`);
            state = 2;
            check.destroy();
        }, timeout);

        check.on('error', (err) => {
            if (err.errno === 'ECONNREFUSED') {
                console.log(`${host}:${port} is closed`);
                state = 1;
                check.destroy();
            }
        });

        check.on('close', () => {
            resolve({port, state, time: new Date().getTime() - start});
        });
    });
}


/**
 * 遍歷檢測所有庫存端口,並記錄結果
 */
function detectAll() {
    async function dectectOne (host, port) {
        let result = await detectOnePromise(host, port);
        console.log(result);
       // TODO 同步存入數據庫
    }
    let host = '127.0.0.1';
    let ports = ['10100','10101','10102'];
    // 遍歷端口,每個端口的檢測同時開始執行
    for (port of ports) {
        dectectOne(host, port);
    }
}

detectAll();

如果希望獲取全部完成的時機,可以使用Promise.all()。

利用了幾個機制:

  • await可以把promise對象的resolve中的值提出來。
  • async函數,若不加await直接調用,會異步執行。 即使async內部會同步執行完後才返回值,不加await也會立刻異步返回一個Promise對象。
  • Promise.all(Iterable).then((valueArray)=>())會等Iterable對象中所有Promise對象執行完畢後,再執行then()。所有結果包含在valueArray中。
發佈了32 篇原創文章 · 獲贊 8 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章