简体   繁体   English

无法解决承诺链

[英]Unable to resolve promise chain

I am trying to write a Sequelize migration script win which I am trying to update my database but it is having many asynchronous operations (database queries and then updating database with particular id) 我正在尝试编写一个Sequelize迁移脚本,它正在尝试更新数据库,但是它具有许多异步操作(数据库查询,然后使用特定的ID更新数据库)

Here is my code 这是我的代码

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);
      }) 

Actually what I am trying to do is I am trying to take the list of all orgEntries from the database and then I am finding maximum serial number for that organization_id and then updating that particular orgEntry and like this all these operations in a loop 实际上,我正在尝试从数据库中获取所有orgEntries的列表,然后查找该organization_id最大序列号,然后更新该特定的orgEntry,并像这样在循环中进行所有这些操作

Now the problem is coming all the things are going in order but after finding max_serial_no it is not updating the database and I am not able to resolve what I should do to make that asynchronous call work in this order 现在问题来了,所有事情都按顺序进行,但是找到max_serial_no它没有更新数据库,而且我无法解决我应该怎么做才能使异步调用按此顺序工作

I think you can solve this in two ways: 我认为您可以通过两种方式解决此问题:

Simultaneously Promises 同时承诺

In a following code I removed forEach in favor of Promise.all() and map() 在以下代码中,我为了Promise.all()map()删除了forEach

  • The map() method create (and return) a new array with the results of calling a provided function on every element in the calling array. map()方法创建(并返回)新数组,并在调用数组中的每个元素上调用提供的函数。

Example: 例:

let numbers = [1, 2, 3]
let doubledNumbers = numbers.map(n => n * 2)
// doubledNumbers [2, 4, 6]
  • The Promise.all() method take an array of Promises as argument and returns a single Promise that will be resolved when all promises will be resolved or rejected if one promise failed Promise.all()方法将一组Promises作为参数,并返回一个Promise,当所有Promise将被解决或被拒绝(如果一个Promise失败)时,该Promise将被解决。

Example: 例:

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

Result: 结果:

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

Step by step Promises with reduce() method 分步承诺与reduce()方法

  • The reduce() method applies a function against an accumulator and each element in the array (from left to right) to reduce it to a single value. reduce()方法对一个累加器和数组中的每个元素(从左到右)应用一个函数,以将其减小为单个值。 (from MDN web docs) (来自MDN网络文档)

Example: 例:

let items = [{ name: 'pencil', price: 2 }, { name: 'book', price: 10 }]
let total = items.reduce((total, item) => total += item.price, 0)
// total: 12

Result: 结果:

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')
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM