Невозможно разрешить цепочку обещаний - PullRequest
0 голосов
/ 25 апреля 2018

Я пытаюсь написать выигрыш сценария миграции Sequelize, который я пытаюсь обновить мою базу данных, но она выполняет много асинхронных операций (запросы к базе данных, а затем обновляет базу данных с определенным идентификатором)

Вот мойкод

return db.organizationEntries
      .findAll()
      .then((entries) => {
        return entries.forEach(entry => {
          console.log(entry);
          db.organizationEntries
            .findAll({
              attributes: [
                [
                  db.sequelize.fn(
                    'MAX',
                    db.sequelize.col('organizationEntries.serial_number')
                  ),
                  'maximum_serial_no'
                ]
              ],
              where: {
                organizationId: entry.organizationId
              }
            })
            .then(orgEntry => {
              console.log(orgEntry[0].dataValues.maximum_serial_no);
              let data = { serialNumber: orgEntry[0].dataValues.maximum_serial_no + 1 };
              console.log(data)

              //problem 
              db.organizationEntries.update(data, {
                where: {
                  id: entry.id
                }
              })
                .then((result) => {
                  console.log(result);

                })
            });
          // promises.push(promise);
        });
        // return Promise.all(promises);
      }) 

На самом деле я пытаюсь взять список всех orgEntries из базы данных, а затем нахожу максимальный серийный номер для этого organization_id и затем обновляю его.конкретный orgEntry и тому подобное все эти операции в цикле

Теперь проблема состоит в том, что все идет по порядку, но после нахождения max_serial_no он не обновляет базу данных, и я не могу решить, что ядолжен сделать так, чтобы этот асинхронный вызов работал в этом порядке

1 Ответ

0 голосов
/ 25 апреля 2018

Я думаю, вы можете решить эту проблему двумя способами:

Одновременные обещания

В следующем коде я удалил forEach в пользу Promise.all() и map()

  • Метод map() создает (и возвращает) новый массив с результатами вызова предоставленной функции для каждого элемента в вызывающем массиве.

Пример:

let numbers = [1, 2, 3]
let doubledNumbers = numbers.map(n => n * 2)
// doubledNumbers [2, 4, 6]
  • Метод Promise.all() принимает массив Обещаний в качестве аргумента и возвращает одно Обещание, которое будет разрешено, когда все обещания будут разрешены или отклонены в случае сбоя одного обещания

Пример:

let promise1 = findUserById(5)
let promise2 = findUserFriends(5)
Promise.all([promise1, promise2])
.then(values => {
  // values: [user object, list of user friends]
})

Результат:

db.organizationEntries.findAll()
.then(entries => {
  return Promise.all(entries.map(entry => {
    console.log(entry)

    return db.organizationEntries.findAll({
      where: {
        organizationId: entry.organizationId
      },
      attributes: [
        [
          db.sequelize.fn('MAX', db.sequelize.col('organizationEntries.serial_number')),
          'maximum_serial_no'
        ]
      ]
    })
    .then(orgEntry => {
      console.log(orgEntry[0].dataValues.maximum_serial_no)
      let data = { serialNumber: orgEntry[0].dataValues.maximum_serial_no + 1 }
      console.log(data)
      return db.organizationEntries.update(data, { where: { id: entry.id } })
    })
  }))
})
.then(result => {
  // result: Array of updated organizationEntries
  console.log(result)
})

Пошаговые обещания с reduce() методом

  • Метод reduce() применяет функцию к аккумулятору и каждому элементу в массиве (слева направо), чтобы уменьшить его до одного значения. (из документов MDN)
* +1040 * Пример: * * тысяча сорок один
let items = [{ name: 'pencil', price: 2 }, { name: 'book', price: 10 }]
let total = items.reduce((total, item) => total += item.price, 0)
// total: 12

Результат:

db.organizationEntries.findAll()
.then(entries => {
  return entries.reduce((previousPromise, entry) => {
    console.log(entry)

    return previousPromise
    .then(_ => {
      return db.organizationEntries.findAll({
        where: {
          organizationId: entry.organizationId
        },
        attributes: [
          [
            db.sequelize.fn('MAX', db.sequelize.col('organizationEntries.serial_number')),
            'maximum_serial_no'
          ]
        ]
      })
    })
    .then(orgEntry => {
      console.log(orgEntry[0].dataValues.maximum_serial_no)
      let data = { serialNumber: orgEntry[0].dataValues.maximum_serial_no + 1 }
      console.log(data)
      return db.organizationEntries.update(data, { where: { id: entry.id } })
    })
    .then(updatedEntry => {
      console.log(updatedEntry)
    })
  }, Promise.resolve())
})
.then(result => {
  // result: Last updated organization entry
  console.log('finished')
})
...