猫鼬脚本种子数据库挂起

时间:2020-02-06 17:57:55

标签: javascript mongodb mongoose

我有以下脚本:

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(),我的脚本可以正常工作但会挂起。

执行完脚本后如何使脚本工作并退出?

3 个答案:

答案 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()