node.js - 异步循环没有等待
问题描述
我正在使用 node-async-loop 进行异步编程
var array = ['item0', 'item1', 'item2'];
asyncLoop(array, function (item, next)
{
do.some.action(item, function (err)
{
if (err)
{
next(err);
return;
}
next();
});
}, function (err)
{
if (err)
{
console.error('Error: ' + err.message);
return;
}
console.log('Finished!');
});
像这样,我使用三个异步循环,一比一。我只想在第三个内部循环结束后发送响应。我该怎么做?这是节点异步循环的链接(https://www.npmjs.com/package/node-async-loop)
这是我写的代码,但是当最后一个循环完成时我想响应它说可以在发送给客户端后设置标题。同样在控制台日志中,每当数据来自查询时,我都会获取数据。
const id = req.params.id;
finalData = [];
tb_user.findOne({ where: { id: id } }).then((userRiverSys, err) => {
if (userRiverSys) {
// console.log(userRiverSys.regionJson)
asyncLoop(userRiverSys.regionJson, function (item, next) {
// console.log("item", item);
tb_riverSystems.findAll(
{
where: { regionId: item.id }
}).then((findriverSys, err) => {
if (err) {
next(err);
return;
}
// console.log("findriverSys", findriverSys);
if (findriverSys) {
asyncLoop(findriverSys, function (item1, next1) {
if (err) {
next(err);
return;
}
// console.log("item1", item1.dataValues);
tb_facilities.findAll(
{
where: { riverSystemId: item1.dataValues.id }
}).then((findFacilities) => {
if (findFacilities) {
// console.log("findFacilities", findFacilities[0].dataValues.name);
asyncLoop(findFacilities, function (item2, next2) {
if (err) {
next(err);
return;
}
tb_userAccess.findAll(
{
where: { facilityId: item2.dataValues.id }
}).then((userAccessFacilities, err) => {
// console.log("userAccessFacilities", userAccessFacilities[0].dataValues);
// var i = 0;
asyncLoop(userAccessFacilities, function (item3, next3) {
finalData.push({
UserId: item3.userid,
facilityId: item3.facilityId,
})
next3();
},
function (err) {
if (err) {
console.error('Error: ' + err.message);
return;
}
// i++;
// console.log('Finished!!!!');
// if (userAccessFacilities.length === i) {
// console.log("finalData", i);
// // res.json({"status":"true", "message":"update OrgChallenge"})
// }
})
return res.json({"status":"true", "message":"update OrgChallenge"})
// console.log("finalData", finalData);
})
next2();
}, function (err) {
if (err) {
console.error('Error: ' + err.message);
return;
}
console.log('Finished!!!');
});
}
});
next1();
}, function (err) {
if (err) {
console.error('Error: ' + err.message);
return;
}
console.log('Finished!!');
});
}
});
next();
}, function (err) {
if (err) {
console.error('Error: ' + err.message);
return;
}
console.log('Finished!');
});
} else {
console.log("err3", err)
}
})
解决方案
如果您承诺您的异步操作(因此它返回一个承诺),那么您可以只使用常规for
循环,async/await
并且不需要第 3 方库来对您的异步循环进行排序。这是现代 Javascript:
const { promisify } = require('util');
do.some.actionP = promisify(do.some.action);
async function someFunction() {
const array = ['item0', 'item1', 'item2'];
for (let item of array) {
let result = await do.some.actionP(item);
// do something with result here
}
return someFinalResult;
}
someFunction().then(result => {
console.log(result);
}).catch(err => {
console.log(err);
});
仅供参考,在实际代码中,许多(甚至大多数)异步操作现在已经提供了其 API 的承诺版本,因此通常您甚至不需要再执行承诺步骤。例如,几乎所有数据库都已经提供了一个可以直接使用的 Promise 接口。
推荐阅读
- c++ - 我是初学者,刚开始学习 c++,我在 windows 10 64 位 pc 上使用 eclipse [版本:Helios Service Release 2 Build id:20110218-0911]
- printing - 如何限制 Fortran 中每行打印的字符数?
- ios - 如果要使用主故事板文件,应用程序委托必须实现 window 属性。(迅速)
- java - 在使用嵌套 for 循环时,if 语句是否会等到循环结束后再继续执行 if 语句代码?
- javascript - 将数组中的值放入文本框中
- javascript - 在 Angular 中使用 BehaviourSubject 在两个组件之间进行通信
- domain-driven-design - 工厂模式实现类在 DDD 的干净架构中位于何处
- reactjs - Handling error in React with Formik: Objects are not valid as a React child
- python - What is the built-in way to ensure Python3.x doesn't implicitly convert bytes to other class when indexing lists?
- ajaxform - 未捕获的 SyntaxError:意外的标识符问题在重新加载时不断出现