级联数组的诺言的正确方法(猫鼬示例)

时间:2018-06-28 00:02:11

标签: javascript mongoose promise

我需要了解使用猫鼬层叠诺言的正确方法。

我的函数createCustomerBills收到一个客户ID列表,对于每个ID,我需要创建一个简单的账单。

代码如下:

const createCustomerBill = (customer) => {
    return BillModel.create({
        customer_id: customer.id,
        value: 100
    });
}

const createCustomerBills => (customerIds) => {
    let criteria = {
        _id: { $in: customerIds }
    };

    return CustomerModel.find(criteria)
    .then(result => {
        return result.map(customer => {
            return createCustomerBill(customer);
        }
    })
    .then(result => {
        return CustomerModel.update(
                { _id: customer.id }, 
                { status: "BillCreated" }
        );
    });
}

以下是步骤: 1.获取所有客户的清单 2.为每个客户创建账单 3.对于创建的每个帐单,更新客户状态

如果这是正确的方法以及可能存在的弊端,我需要咨询。

2 个答案:

答案 0 :(得分:2)

因为您正在映射CustomerModel.find的结果,所以返回该数组将不会等待promise完成以运行下一个.then,因为数组不是Promise

这就是Promise.all进来的地方

此外,由于您需要单独更新每个帐单,因此承诺链的一部分需要位于.map迭代中

const createCustomerBill = customer => 
    BillModel.create({
        customer_id: customer.id,
        value: 100
    });

const createCustomerBills => customerIds => {
    let criteria = {
        _id: { $in: customerIds }
    };

    return CustomerModel.find(criteria)
    .then(result => 
        Promise.all(
            result.map(customer => createCustomerBill(customer)
                .then(result => CustomerModel.update({ _id: customer.id }, { status: "BillCreated" }))
            )
        )
    )
    .then(result => {
        // all bills are now processed 
    });
}

答案 1 :(得分:1)

IMO,这是一种可能的工作方式

const createCustomerBill = (customer) => {
  return BillModel.create({
    customer_id: customer.id,
    value: 100,
  });
}

const createCustomerBills => (customerIds) => {
  const criteria = {
    _id: {
      $in: customerIds,
    },
  };

  return CustomerModel.find(criteria)
    .then((customers) => Promise.all(customers.map(x => createCustomerBill(x)
      .then(() => CustomerModel.update({
        _id: x.id,
      }, {
        status: "BillCreated"
      })))))
    .then(() => console.log('over'))
    .catch(e => console.log(e));
}


这里使用了很棒的async/await

const createCustomerBill = customer => BillModel.create({
  customer_id: customer.id,
  value: 100,
});

const updateCustomer = customer => CustomerModel.update({
  _id: x.id,
}, {
  status: 'BillCreated',
});

const createBillAndUpdateCustomer = async(customer) => {
  await createCustomerBill(customer);
  
  await updateCustomer(customer);
};

const createCustomerBills => async(customerIds) => {
  const customers = await CustomerModel.find({
    _id: {
      $in: customerIds,
    },
  });

  await Promise.all(customers.map(x => createBillAndUpdateCustomer(x)));

  console.log('over');
}