【问题标题】:For loop inside promises chained in transaction in Sequelize在 Sequelize 中的事务中链接的承诺中的 For 循环
【发布时间】:2018-09-21 13:27:00
【问题描述】:

我正在构建一个 nodeJS、hapiJS 和 Sequelize(使用 PostgreSQL)应用程序,当我在与 Sequelize 的事务中链接的 Promise 中使用 for 循环时遇到一些问题。

我想用内容列表中的不同内容查询我的数据库。

我已经使用 Promises.all() 或 Promise.map() 建立了一些解决方案,但我无法将其应用于我的问题。

谁能解释我正确的方向?

db.User.sequelize.transaction(function(t){
         return db.User.findOrCreate({
            where: {
                name: request.payload.user.id
            },
            transaction: t
        })
        .then( userResult => {
            return db.Order.findOrCreate({
                where: {
                    userId : userResult[0].dataValues.userId,
                    code : request.payload.order.code,
                    brand : request.payload.order.brand,
                    date : request.payload.date
                },
                transaction: t
            })
        })
        // ############## HERE ##################
        .then( orderResult => {
            console.log("I WILL BE PRINTED")
            for (var i = 0; i < request.payload.content; i++){
                console.log("I WILL NOT BE PRINTED")
                db.Product.findOrCreate({
                    where :{ean : request.payload.content[i].product.ean},
                    transaction: t  // FAIRE BOUCLE CONTENT
                })
                .then( productResult => {
                    return db.Info.findOrCreate({
                        where: {
                            //TODO : prefix et password
                            productId: productResult[0].dataValues.productId,
                            orderId: orderResult[0].dataValues.orderId
                        }
                    }).then( infoResult => {
                        console.log(productResult)
                        return db.Range.create({
                            infoId : infoResult[0].dataValues.infoId,
                            low : productResult[0].dataValues.offset,
                            high : request.payload.content[i].quantity
                        })
                    })
                })
            }
        })
        .then(res => { return console.log("ok")})
    })

【问题讨论】:

  • 如果循环内的console.log 没有显示出来,那么问题在于循环的条件。但是您需要使用Promise.allPromise.map 来解决它。为什么您认为它们不能应用于您的问题?
  • @t.niese 我的意思是我没有成功应用它们

标签: javascript node.js promise sequelize.js


【解决方案1】:

这里的问题是,您从一开始就永远不会创建承诺。您的循环根本不返回承诺,Promise.all 仅在所有承诺都解决后才会返回。

由于您使用的是 es6 语法,您不妨使用map 方法而不是for 循环。这是一种更实用的方法。

这会导致类似:

Promise.all(request.payload.content.map(content => {
    db.Product.findOrCreate({
        where :{ean : content.product.ean},
        transaction: t
    })
})

如果您更喜欢坚持 for 循环,策略是相同的。将您的循环包装在 promise.all 中,这会将您的查询返回的所有承诺存储在一个数组中。当循环结束并且所有的承诺都被解决时,promise.all 将被触发。请注意,如果单个 Promise 被拒绝,promise.all 将被拒绝

【讨论】:

  • 你在findOrCreate的异步调用完成之前调用resolve()。而findOrCreate 已经返回了一个 Promise,所以不需要将它包装到另一个 Promise 中。
  • 感谢您的回复,可以了!您应该通过where :{ean : content.product.ean} 编辑where :{ean : request.payload.content[i].product.ean}
  • 很高兴它帮助了你!你说得对,我只是复制粘贴了你的循环并没有改变核心,忘记了,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-01
  • 2017-08-25
  • 2017-12-10
  • 1970-01-01
  • 2023-03-17
  • 2016-10-11
  • 1970-01-01
相关资源
最近更新 更多