简体   繁体   English

循环中的异步调用延迟

[英]Async calls in loop delayed

I have a function which makes two asynchronous calls to the database inside a loop.我有一个 function 在循环内对数据库进行两次异步调用。 The issue is that the return function works before the data from the loop is retrieved.问题是返回 function 在检索来自循环的数据之前起作用。

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

You're making all of those calls in parallel by doing them in the map callback.您可以通过在map回调中并行执行所有这些调用。 If you really want to do that, you need to wait for those calls to settle by using Promise.all :如果您真的想这样做,则需要使用Promise.all等待这些呼叫解决:

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

If you want to do them in series instead, use a for loop and await each response.如果您想连续执行它们,请使用for循环并等待每个响应。 :-) But it looks like parallel is okay. :-) 但看起来并行是可以的。

You need to await the map and then it will wait for it otherwise being async doesn't make it wait it actually means it will go on to the next code unless you tell it to await .您需要await map ,然后它将等待它,否则异步不会使其等待它实际上意味着它将go 进入下一个代码,除非您告诉它await like so: const customerList = await customers.map.... Now since map does not return a promise you would need to wrap it in a promise either with Promise.all or an individual promise. like so: const customerList = await customers.map.... Now since map does not return a promise you would need to wrap it in a promise either with Promise.all or an individual promise.

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

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