![](/img/trans.png)
[英]JS node, waiting for function to complete before executing second function
[英]Waiting for an function to complete before executing the next step - node js
我是 node js 的新手,目前正在學習 promises 和 await/async。 我嘗試了下面的代碼,但不知道如何讓代碼等到函數托管完成。 我也嘗試過承諾,但等不及了。
var ping = require('ping');
var hoststatus
var hosts = ['google.com'];
async function test()
{
var connected = await hostping(hosts);
console.log('connected--------------', connected)
connected.then(function(hoststatus) {
console.log('hoststatus--------------', hoststatus)
if (hoststatus == 1) {
console.log('faaaaaaaail-------------')
} else {
console.log('passssssssssssssssss-----------')
}
});
}
async function hostping(hosts) {
console.log('hosts-----------', hosts)
await hosts.forEach(async function(host) {
await ping.sys.probe(host, async function(isAlive) {
var msg = isAlive ? 'host ' + host + ' is alive' : 'host ' + host + ' is dead';
console.log(msg);
if (isAlive == 'false') {
hoststatus = 1
}
});
});
return hoststatus;
}
test()
這應該按照您的意願進行,我們使用 for .. of 循環按順序迭代主機。
ping 庫還有一個承諾包裝器,允許您跳過使用回調。
您也可以使用 Promise.all 一次完成所有 ping 和探測,但我不相信這是您想要做的。
如果您想一次執行所有 ping,我已經包含了一個使用 Promise.all 的 hostpingVer2。
const ping = require('ping');
const hosts = ['google.com', 'amazon.com', 'itdoesntexist'];
async function test() {
console.log('hosts: ', hosts)
const results = await hostping(hosts);
console.log('ping results: ', results);
}
async function hostping(hosts) {
const results = [];
for(let host of hosts) {
let probeResult = await ping.promise.probe(host);
results.push( { host, hoststatus: probeResult.alive ? 0: 1, alive: probeResult.alive } );
}
return results;
}
async function hostpingVer2(hosts) {
const probeResults = await Promise.all(hosts.map(host => ping.promise.probe(host)));
return probeResults.map(probeResult => {
return { host: probeResult.host, hoststatus: probeResult.alive ? 0: 1, alive: probeResult.alive }
});
}
test();
您在forEach
內使用 await 這不應該工作,因為 forEach 不支持承諾。 考慮更改它for..of
或promise.all
。
此外,您的探測函數是一種不返回承諾的回調樣式。 您需要將它包裝在一個承諾中以等待它。
function probe(host) {
return new Promise((resolve, reject) => {
ping.sys.probe(host, function (isAlive) {
const msg = isAlive ? `host ${host} is alive` : `host ${host} is dead`;
console.log(msg);
resolve(isAlive);
});
});
}
async function hostping(hosts) {
console.log("hosts-----------", hosts);
for(const host of hosts) {
// eslint-disable-next-line no-loop-func
// eslint-disable-next-line no-await-in-loop
const isAlive = await probe(host);
if (isAlive === "false") {
hoststatus = 1;
}
}
return hoststatus;
}
要執行您想要的操作,您應該使用 ping 和 for..of 的承諾包裝器,因為 forEach 不適用於異步。
下面是修改您的代碼以使流程按預期工作:
const ping = require('ping');
const hosts = ['google.com', 'yahoo.com'];
async function test()
{
const status = await hostping(hosts);
if (status) {
console.log('All hosts are alive');
} else {
console.log('Some/all hosts are dead');
}
}
function hostping(hosts) {
let status = true;
return new Promise(async function(resolve, reject) {
for (const host of hosts) {
const res = await ping.promise.probe(host);
var msg = `host ${host} is ${res.alive ? 'alive' : 'dead'}`;
console.log(msg);
if (!res.alive) { status = false; }
}
console.log('all host checks are done, resolving status');
resolve(status);
});
}
test()
如果您有興趣了解有關異步的更多信息,這些是值得閱讀的好帖子: https : //www.coreycleary.me/why-does-async-await-in-a-foreach-not-actually-await/
https://itnext.io/javascript-promises-and-async-await-as-fast-as-possible-d7c8c8ff0abc
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.