循环中的异步调用延迟
Async calls in loop delayed
我有一个函数可以在一个循环中对数据库进行两次异步调用。问题是 return 函数在从循环中检索数据之前起作用。
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()
你需要 await
地图,然后它会等待它,否则异步不会让它等待它实际上意味着它 将 继续下一个代码,除非你告诉它 await
。像这样:
const customerList = await customers.map....
现在因为 map 没有 return 承诺,你需要用 Promise.all
或单独的承诺将它包装在承诺中。
您可以通过在 map
回调中并行进行所有这些调用。如果你真的想这样做,你需要等待这些调用通过使用 Promise.all
:
来解决
const customerList = await Promise.all(customers.map(async (customer) => {
// ...
}));
如果您想依次进行,请使用 for
循环并等待每个响应。 :-) 但看起来并行没问题。
我有一个函数可以在一个循环中对数据库进行两次异步调用。问题是 return 函数在从循环中检索数据之前起作用。
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()
你需要 await
地图,然后它会等待它,否则异步不会让它等待它实际上意味着它 将 继续下一个代码,除非你告诉它 await
。像这样:
const customerList = await customers.map....
现在因为 map 没有 return 承诺,你需要用 Promise.all
或单独的承诺将它包装在承诺中。
您可以通过在 map
回调中并行进行所有这些调用。如果你真的想这样做,你需要等待这些调用通过使用 Promise.all
:
const customerList = await Promise.all(customers.map(async (customer) => {
// ...
}));
如果您想依次进行,请使用 for
循环并等待每个响应。 :-) 但看起来并行没问题。