如何等待异步操作循环?
How to Await a Loop of Async Operations?
我有一个补丁端点,它接受要更新的字段主体、遍历每个字段并更新正确的值。一旦完成所有这些事情,我想做一些事情发送响应,但我不知道如何等待操作循环。如果它是一个单独的操作,我可以只添加 .then(),但在这种情况下这不起作用。什么是优雅的解决方案?
代码:
const updateUser = (req, res) => {
const db = mongoConnection.getDb();
for (key in req.body) {
db.collection('users').updateOne(
{username: req.query.username},
{$set: {[key]: req.body[key]}}
)
}
// send response once for loop is done
}
我认为一个简单的答案是将 for 循环隐藏在异步函数中,然后在端点中使用它。
const updateUserField = async () =>
db.collection("users").updateOne(
{
username: req.query.username,
},
{
$set: { [key]: req.body[key] },
}
);
const updateUserEndpoint = (req, res) => {
for (let field of req.body) {
await updateUserField(field);
}
res.status(200).send('updated');
}
然后,为了进行测试,您可以使用注入函数本身的函数包装端点:
const updateUserEndpoint = (userUpdateFunc) => userUpdateFunc(req, res);
这种模式称为依赖注入 - 在为端点编写单元测试时,您只需将 userUpdateFunc
替换为您想要使用的任何模拟函数。这消除了在测试中对函数进行 monkeypatch 的需要。
您可以标记外部函数 async
和 await
循环内的每个数据库更新。然后你就会知道在循环完成后,所有的数据库更新都完成了。
更好的方法是 运行 并行更新,因为它们不相互依赖。您可以使用 Promise.allSettled()
它接受一组承诺并在最后一个完成时解决。
const updateUser = async (req, res) => {
const db = mongoConnection.getDb();
const dbUpdates = Object.entries(req.body).map((key, value) => {
return db.collection('users').updateOne(
{ username: req.query.username },
{ $set: { [key]: value }}
);
});
await Promise.allSettled(dbUpdates);
// Send response, at this point all DB updates are done
};
我有一个补丁端点,它接受要更新的字段主体、遍历每个字段并更新正确的值。一旦完成所有这些事情,我想做一些事情发送响应,但我不知道如何等待操作循环。如果它是一个单独的操作,我可以只添加 .then(),但在这种情况下这不起作用。什么是优雅的解决方案?
代码:
const updateUser = (req, res) => {
const db = mongoConnection.getDb();
for (key in req.body) {
db.collection('users').updateOne(
{username: req.query.username},
{$set: {[key]: req.body[key]}}
)
}
// send response once for loop is done
}
我认为一个简单的答案是将 for 循环隐藏在异步函数中,然后在端点中使用它。
const updateUserField = async () =>
db.collection("users").updateOne(
{
username: req.query.username,
},
{
$set: { [key]: req.body[key] },
}
);
const updateUserEndpoint = (req, res) => {
for (let field of req.body) {
await updateUserField(field);
}
res.status(200).send('updated');
}
然后,为了进行测试,您可以使用注入函数本身的函数包装端点:
const updateUserEndpoint = (userUpdateFunc) => userUpdateFunc(req, res);
这种模式称为依赖注入 - 在为端点编写单元测试时,您只需将 userUpdateFunc
替换为您想要使用的任何模拟函数。这消除了在测试中对函数进行 monkeypatch 的需要。
您可以标记外部函数 async
和 await
循环内的每个数据库更新。然后你就会知道在循环完成后,所有的数据库更新都完成了。
更好的方法是 运行 并行更新,因为它们不相互依赖。您可以使用 Promise.allSettled()
它接受一组承诺并在最后一个完成时解决。
const updateUser = async (req, res) => {
const db = mongoConnection.getDb();
const dbUpdates = Object.entries(req.body).map((key, value) => {
return db.collection('users').updateOne(
{ username: req.query.username },
{ $set: { [key]: value }}
);
});
await Promise.allSettled(dbUpdates);
// Send response, at this point all DB updates are done
};