首页 > 解决方案 > 在 array.foreach 中查询数据库 Sequelize

问题描述

使用 array.forEach 从 sequelize 修改结果集。

我想遍历返回的购物车,访问每个元素的数据库并添加一些属性并返回。

const promiseInvoices = [];

  await ShoppingCart.findAll({
    where: {
      // eslint-disable-next-line object-shorthand
      cart_id: cartItem.cart_id,
    },
  }).then(result => {
   result.forEach(cartItem2 => {
      const prod = Product.findByPk(cartItem2.product_id);
      console.log(prod);

      let cartItem3 = {};
      const total = prod.price * cartItem2.quantity;
      cartItem3.cart_id =  cartItem2.cart_id;
      cartItem3.product_id =cartItem2.product_id;
      cartItem3.attributes  =cartItem2.attributes;
      cartItem3.quantity  =cartItem2.quantity ;
      cartItem3.price = prod.price;
      cartItem3.name = prod.name;
      cartItem3.image = prod.image2;
      cartItem3.item_id = cartItem2.item_id;
      cartItem3.subtotal = total;

    return promiseInvoices.push(cartItem3);
    });
  });

返回 shoppingCart,访问每个 shoppingcart 对象的数据库,并获取产品以填充每个 shoppingCart 项目的值。对 Product.findByPk 的调用返回一个可用的承诺,如下所示:

Promise [Object] {
      _bitField: 0,
      _fulfillmentHandler0: undefined,
      _rejectionHandler0: undefined,
      _promise0: undefined,
      _receiver0: undefined }

标签: node.jsexpresssequelize.js

解决方案


  1. 所有 Sequelize CRUD 调用都是异步的,这意味着它们会返回一个 Promise,因此您必须await对它们进行操作。您收到Promise返回的对象而不是带有详细信息的产品的原因是您没有等待findByPk调用完成。

  2. forEach构造不支持异步操作。即使您使array.forEach回调异步,它也不会起作用,并且仍然返回Promise对象而不是带有详细信息的产品。

要解决此问题,您需要等待异步findByPk调用并使用支持异步操作的循环。您可以将for...of循环用于您的用例。

const promiseInvoices = []

await ShoppingCart.findAll({
    where: {
        cart_id: cartItem.cart_id
    }
}).then(result => {

    // for...of loop that supports await
    for await (const cartItem2 of result){
        // Make sure to wait on all your sequelize CRUD calls
        const prod = await Product.findByPk(cartItem2.product_id)

        // It will now wait for above Promise to be fulfilled and show the proper details
        console.log(prod)

        let cartItem3 = {}
        const total = prod.price * cartItem2.quantity
        cartItem3.cart_id = cartItem2.cart_id
        cartItem3.product_id = cartItem2.product_id
        cartItem3.attributes = cartItem2.attributes
        cartItem3.quantity = cartItem2.quantity
        cartItem3.price = prod.price
        cartItem3.name = prod.name
        cartItem3.image = prod.image2
        cartItem3.item_id = cartItem2.item_id
        cartItem3.subtotal = total

        // Simple push will work in this loop, you don't need to return anything
        promiseInvoices.push(cartItem3)
    }
})

推荐阅读