Node.js 节点js等待函数返回以继续for循环
我有一个for循环,它在每个步骤中调用一个函数 该函数调用API,我不知道需要多长时间才能得到响应 我需要等待函数Node.js 节点js等待函数返回以继续for循环,node.js,for-loop,Node.js,For Loop,我有一个for循环,它在每个步骤中调用一个函数 该函数调用API,我不知道需要多长时间才能得到响应 我需要等待函数updatePE()返回一个值,然后循环进入下一步 db.query("SELECT * FROM tb_table where active = true;", (err, result) => { if (err) {console.log('ERROR'); return; } for (const key in Object.keys(result.rows))
updatePE()
返回一个值,然后循环进入下一步
db.query("SELECT * FROM tb_table where active = true;", (err, result) => {
if (err) {console.log('ERROR'); return; }
for (const key in Object.keys(result.rows)) {
updatePE(result.rows[key].b,result.rows[key].s,result.rows[key].k);
}
});
如果updatePE()
是一个同步函数,那么它将等待该函数调用的返回,如果是async
函数,那么尝试将wait
放在该函数前面,直到函数返回
wait updatePE()//确保updatePE()是一个异步函数
像这样
async function updatePE(param1, param2, param3){
return new Promise((resolve, reject)=>{
//do something and call
//resolve(true)
})
}
确保只能在async
函数中调用wait
,因此调用方函数也必须是async
(async function(){
db.query("SELECT * FROM tb_table where active = true;", (err, result) => {
if (err) {console.log('ERROR'); return; }
for (const key in Object.keys(result.rows)) {
await updatePE(result.rows[key].b,result.rows[key].s,result.rows[key].k);
}
});
})()
假设您的
update
函数是异步的(基于承诺),并且您可以使用async/await
(至少需要节点8.x),那么您可以以一种所有更新都将并行发生的方式编写代码(从代码的角度来看,实际上NodeJS在单线程的执行队列顶部运行):
更多关于JS中的async/await的信息,请参见:
db
库是否公开了Promise接口——它将大大简化您的代码,并提供一致的错误处理方式,而不会带来很多麻烦
如果您希望在现有代码中正确使用Promission,但未使用Promission兼容库,则可以使用:
库及其惊人的bluebird
或Promise.fromCallback
。详情如下:promisifyAll
- 根据以下答案,自己动手:
updatePE
是您自己的函数,我会将该函数转换为承诺或向其添加回调,这样您就知道它何时完成执行
比如说
// Promise implementation
function updatePE(x, y, z) {
return new Promise(function(resolve, reject){
// Do your work here and when is done resolve it
resolve();
});
}
// Callback implementation
function update(x, y, z, callback)
{
// Do your work here and when is done, callback
callback()
}
现在使用异步库可以执行以下操作
// If your updatePE uses callback
async.forEach(result.rows, function(row, callback) {
updatePE(x, y, z, function() {
callback(null)
});
}, function(err){
if (err) {
// Loop is finished with an error
} else {
// Loop is finished without an error
}
});
// If your updatePE uses promise
async.forEach(result.rows, function(row, callback) {
updatePE(x, y, z)
.then(function(){
callback(null)
})
.catch(function(err){
callback(err)
})
}, function(err){
if (err) {
// Loop is finished with an error
} else {
// Loop is finished without an error
}
});
使用异步库实现。它允许您仅在启动回调后才能转到for循环的下一个迭代。像这样:
var async = require('async');
async.forEach(Object.keys(result.rows), async function(key, cb) {
await updatePE(result.rows[key].b,result.rows[key].s,result.rows[key].k);
cb();
}, function(err) {
// Here you know that the loop has completed (with err or success).
});
function updatePE(b, s, k) {
return new Promise(function(resolve, reject) {
// Your update code here.
if(updateSuccessful) resolve();
else reject();
});
}
一定要在updatePE中返回一个承诺。像这样:
var async = require('async');
async.forEach(Object.keys(result.rows), async function(key, cb) {
await updatePE(result.rows[key].b,result.rows[key].s,result.rows[key].k);
cb();
}, function(err) {
// Here you know that the loop has completed (with err or success).
});
function updatePE(b, s, k) {
return new Promise(function(resolve, reject) {
// Your update code here.
if(updateSuccessful) resolve();
else reject();
});
}
到目前为止,您做了哪些尝试?您是否考虑过回电或承诺作为可能的解决方案?据我所知,发电机可以很好地解决此类问题。尽管我对它们的理解还不够自信,无法提供一个简单的例子。根据良好的JS实践(解释如下:),在任何情况下,当我们只想等待多个请求时,
Promise。尽管在for循环中直接使用了wait
,但应使用所有的。从Rasul的问题很难判断代码是必须等待所有更新还是必须按顺序执行(在我看来,后者是一个危险的决定),但我认为Promise.all
可能是一个更好的主意。另外,由于异步作用域在db.query
中的代码之外,因此代码无法工作。我同意,并且我认为,由于这是一个db操作,因此执行顺序是必不可少的,尽管无法确定:P