Объединение нескольких обещаний, l oop по массиву с использованием карты и создание документа mon goose? - PullRequest
1 голос
/ 18 июня 2020

Я получаю список людей из базы данных, используя getPeople(). Как только я получу их как res, я хочу подготовить их для хранения в моем локальном mongodb , если их не существует. Иногда встречаются повторяющиеся записи (для одного id) внутри res. Моя проблема в том, что он не ждет, пока Person.create(pers) завершит sh, продолжает поиск, если этот id уже находится в mongodb, не может найти его, поскольку Person.create(pers) все еще создает его и запускает второй Person.create(pers). .

this.getPeople()
  .then(res => {
    return Promise.all(res.map(pers => {
      pers.birthday = df(pers.birthday, 'dd.mm.yyyy')
      pers.pickedUp = false
      console.log(pers.id)
      return Person
        .find({ id: pers.id })
        .exec()
        .then(found => {
          if (found === undefined || found.length == 0)
            return pers
        })
        .then(pers => {
          return Person
            .create(pers)
            .then(console.log('created'))
            .catch(err => console.log(err))
        })
    }))
  }).catch(err => console.log(err))

Я ожидал, что вывод консоли будет таким:

940191
created
940191
created

Вместо этого я получаю следующее:

940191
940191
created
created

1 Ответ

1 голос
/ 18 июня 2020

Это потому, что Promise.all просто ждет всех обещаний, которые вы mapping. Это не гарантирует какой-либо порядок, в котором выполняются обещания.

Если вы хотите последовательно обрабатывать элементы вашего res -массив, вы можете просто использовать for .. of l oop в сочетании с async/await (обратите внимание, что это все еще требует обработки ошибок, но это должно дать вам кое-что для начала):

async function getPeopleAndCreateIfNotExisting() {
    const persons = [];
    const res = await this.getPeople();

    for (const pers of res) {    
        pers.birthday = df(pers.birthday, 'dd.mm.yyyy');
        pers.pickedUp = false;
        console.log(pers.id)
        const found = await Person
            .find({ id: pers.id }).exec();
        if (found) {
            persons.push(pers);
        } else {
            persons.push(await Person.create(pers));
        }
    }
    return person;
}
...