使用Promise和async-await實現的一個非同步遍歷+同步執行任務的例項
阿新 • • 發佈:2019-01-06
假設我們需要做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中。