我有以下脚本:
const db = require('../db')
const User = require('../models/user')
db.on('error', console.error.bind(console, 'MongoDB connection error:'))
const main = async () => {
const users = [
new User({ name: 'Benny', age: 28, status: 'active' }),
new User({ name: 'Claire', age: 28, status: 'active' })
]
const newUsers = async () => {
await users.forEach(async user => await user.save())
}
await newUsers()
console.log("Created users!")
}
const run = async () => {
await main()
process.exit(0)
}
run()
由于某种原因,process.exit()
在main()
解析之前执行,因此我没有创建任何用户。
如果我删除process.exit()
,我的脚本可以正常工作但会挂起。
执行完脚本后如何使脚本工作并退出?
答案 0 :(得分:0)
等待users.forEach()
不会执行任何操作,因为forEach
没有返回值,因此没有等待的内容。可能会遍历整个列表,然后立即退出,然后从main
返回并在process.exit()
s有机会执行之前调用.save()
。
但是,您可以做的是使用Promise.all()
等待所有诺言完成。这将需要您将每个用户创建的内容映射到Promise中,但这是User.save
函数要做的事情,它将返回Promise。这是一个如何做到这一点的例子:
function save(user) {
// do something async here
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(`${user.name} Saved!`);
resolve()
}, 1500);
});
}
const main = async () => {
const users = [
{ name: 'Benny', age: 28, status: 'active' },
{ name: 'Claire', age: 28, status: 'active' }
]
// map async processes into an array of promises
const newUsers = users.map(user => save(user));
// await the resolution of all promises, then proceeed
await Promise.all(newUsers);
console.log("Created users!")
}
const run = async () => {
await main()
console.log("done")
}
run()
以这种方式进行操作的独特好处是数据库调用将并行发生,这将使播种过程更快。从概念上讲,您要执行的操作将等待每个数据库调用完成,然后再开始下一个数据库调用(又名串行运行)。如果您需要它们按顺序执行,那是一件好事,但是用例似乎并不需要。
答案 1 :(得分:0)
我的同事提出了此解决方案:
const db = require('../db')
const User = require('../models/user')
db.on('error', console.error.bind(console, 'MongoDB connection error:'))
const main = async () => {
const users = [
new User({ name: 'Benny', age: 28, status: 'active' }),
new User({ name: 'Claire', age: 28, status: 'active' })
]
const newUsers = async () => {
await users.reduce(async (promise, user) => {
await user.save()
return promise
}, Promise.resolve())
}
await newUsers()
console.log("Created users!")
}
const run = async () => {
await main()
process.exit()
}
run()
答案 2 :(得分:0)
这是我的解决方案-希望得到一些改进方面的反馈!
const db = require('../db')
const User = require('../models/user')
db.on('error', console.error.bind(console, 'MongoDB connection error:'))
const main = async () => {
const users = [
{ name: 'Benny', age: 28, status: 'active' },
{ name: 'Claire', age: 28, status: 'active' }
]
await User.insertMany(users)
console.log("Created users!")
}
const run = async () => {
await main()
db.close()
}
run()