我有以下代码:
async function seedDb() {
let users: Array<Users> = [ ... ];
applications.map(async (user) => await prisma.user.upsert(
{ create: user, update: {}, where: { id: user.id } }));
}
问题在于,还有其他 SeedDb 函数(例如
seedDb2
)依赖于运行前数据库中存在的用户。但是,当我在 seedDb
中开始所有更新时,我实际上并没有等待(在阻塞的意义上)直到这些功能完成。
我想做的是阻塞,直到地图生成的所有异步函数返回。我如何实现这一目标?
我不完全理解
await
是如何工作的。我知道它允许中断执行并等待在该上下文中直到承诺得到履行,但是如何使其真正阻止执行?类似于threads.join()
?
例如,在 C++ 中,我将创建更新数据库的线程,然后在从 SeedDb 返回之前在最后连接所有线程。在打字稿中推荐的方法是什么?
使用
return await Promise.all(applications.map(async (user) => await prima.user.upsert(...))
(由链接的问题建议)在我看来也是不正确的 - 在由seedDb2
产生的承诺完成之前,不同的函数(seedDb
)可能仍在运行,这就是我的意思试图避免。
[0] 附带问题 - 使用
await Promise.all()
有什么意义? Promise.all
不是已经解决了promise并返回了实际类型吗,为什么我们还要再次调用await?
假设您有一个函数 main() ,它调用 seedUsers() 和 seedComments() ,这需要用户在场。
你可以做的就是让你的 main 函数异步(这仅仅意味着它将成为一个 Promise)并使用 wait 来确保 SeedUsers() 函数在运行 SeedComments() 之前完成执行:
async function seedUsers() {
let users: Array<Users> = [ ... ];
// You must return a single Promise using Promise.all or use Promise.all in the main() function
return Promise.all(applications.map(async (user) => await prisma.user.upsert(
{ create: user, update: {}, where: { id: user.id } })
));
}
async function main() {
// await blocks execution of the Promise until it is fulfilled
await seedUsers();
// this will run after seedUsers has finished
await seedComments();
}
您之前的代码不起作用的原因并不是100%清楚,但由于您在seedDb()函数中使用了.map,但从未返回或使用过Promise,因此您将无法“阻止”代码执行。 .map 应该将数组转换为其他内容,在您的情况下转换为Promises,然后我们使用 Promise.all 创建一个 Promise,一旦 Promise[] 的每个 Promise 得到满足,该 Promise 就会解析。