Mon goose скрипт для зависания базы данных - PullRequest
0 голосов
/ 06 февраля 2020

У меня есть следующий скрипт:

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 голосов
/ 07 февраля 2020

Сотрудник шахты предложил это решение:

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()
0 голосов
/ 10 февраля 2020

Вот мое решение - хотелось бы получить отзыв о его улучшении!

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()
0 голосов
/ 06 февраля 2020

Ожидание users.forEach() ничего не делает, потому что forEach не имеет возвращаемого значения, поэтому ждать нечего. Вероятно, он выполняет итерацию по всему списку, а затем сразу же завершает работу, которая затем возвращается из main и вызывает process.exit() до того, как .save() s получит возможность выполнить.

Однако вы можете сделать следующее: дождитесь всех обещаний до конца sh, используя Promise.all(). Это потребует от вас отображения каждого пользовательского творения в Обещание, но в любом случае ваша функция User.save выполняет возвращение Обещания. Вот пример того, как вы можете это сделать:

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

Очевидным преимуществом этого является то, что вызовы базы данных будут выполняться параллельно, что значительно ускорит процесс заполнения. Концептуально, то, что вы пытались сделать, подождало бы, пока каждый вызов базы данных не завершится sh, прежде чем запускать следующий (он же работает поочередно). Если вам нужно, чтобы они выполнялись по порядку, то это хорошо, но, похоже, ваш сценарий использования этого не требует.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...