【发布时间】:2019-09-24 20:43:24
【问题描述】:
如何在异步循环后运行异步函数?循环不会返回承诺,这意味着您不能使用 await 语法来管理执行顺序。什么是像 Promise 一样管理循环的好方法。
这个问题发生在我的快速路由中。在使用循环从 reids DB 检索数据后,我尝试运行 res.json,但如果我只是将代码放在它之后,res.json 将在循环之前运行。在这里,我使用了一种愚蠢的方式。我检测到循环的最后一次迭代并运行我的 res.json 函数。我认为这不应该是解决这个问题的正确方法。
app.get('/redisApi/v0.3/users', (req, res) => {
var users = [];
redis.scan(0, 'MATCH', 'user:info:*', 'COUNT', 10000).then(key_res => {
//where loop starts
for (let i = 0; i < key_res[1].length; i++) {
redis.hgetall(key_res[1][i]).then(user_res => {
const newOBJ = Object.assign(user_res);
users.push(newOBJ);
//detect last iteration of the loop
if (i === key_res[1].length - 1) {
res.status(200).json({
status: 'success',
data: {
users
}
});
}
});
}
});
});
寻找一种方法来管理循环的执行顺序。
【问题讨论】:
-
不要使用循环,而是使用函数式编程和
.map()传递给Promise.all()的一组承诺 -
顺便说一句,
Object.assign(user_res) === user_res。这不会创建新的对象引用。 -
您可以将
res.status...部分移到 for 循环之外,避免每次都检查它是否是最后一个。 -
@solarc 我试过了, res.status 会在循环之前运行。
-
@solarc 不,你不能。每次迭代的主体都发生在异步回调中。正如问题正确指出的那样,“之后”循环实际上并没有在迭代之后按顺序执行。
标签: javascript loops asynchronous