循环中的异步调用被延迟

时间:2019-11-04 11:12:40

标签: javascript database async-await knex.js

我有一个函数,可以在循环内对数据库进行两个异步调用。问题是返回函数在从循环中检索数据之前起作用。

const myFunc = async (customers) => {
  const customerList = customers.map(async (customer) => {
    const cashCollected = await knex('cash_collections')
      .sum('amount_collected as amount')
      .where('account_code', customer.code)
      .first();
    const orderValue = await knex('orders')
      .sum('discounted_price as amount')
      .where('customer_id', customer.id)
      .first();
    const customerData = {
      name: customer.name,
      outstandingBalance: (orderValue.amount - cashCollected.amount),
    };
    // This line works after console.log(customerList);
    console.log(customerData);
    return customerData;
  });
   // console and return works before data is retrieved 
   // (before console.log(customerData) is run)
  console.log(customerList);
  return customerList;
};

// Function is called in another place
myFunc()

2 个答案:

答案 0 :(得分:5)

您正在map回调中并行进行所有这些调用。如果您确实想这样做,则需要使用Promise.all等待这些呼叫解决:

const customerList = await Promise.all(customers.map(async (customer) => {
    // ...
}));

如果您要依次进行处理,请使用for循环并等待每个响应。 :-)但是看起来并行是可以的。

答案 1 :(得分:0)

您需要npm run debug 映射,然后它将等待它,否则异步就不会使其等待,这实际上意味着它将转到下一个代码,除非您告诉到await。像这样: await 现在,由于map不返回承诺,因此您需要使用const customerList = await customers.map....或单独的承诺将其包装在承诺中。