1. 程式人生 > >使用Promise和async-await實現的一個非同步遍歷+同步執行任務的例項

使用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中。