如何解决如何处理延迟的承诺解决方案?
我的代码可以处理各种情况,并且很长,因此,我用下面的简化伪代码进行了复制:
const sendOrder = async function (Order) {
return new Promise(async (resolve) => {
console.log("order about to be place for " + Order.id + " at " + isoTime());
try {
const orderResponse = await sendOrderToBroker(Order);
console.log("order " + Order.id + "sent to broker at " + isoTime());
//Update db with details about successful order placement
models.orders
.update({
//Order status details
})
.then((countRowsUpdated) => {
console.log(
`Order ${orderId} success - ${countRowsUpdated} row(s) updated at time ${isoTime()}`
);
resolve(countRowsUpdated);
});
} catch (error) {
//Update db with details about failed order placement
models.orders
.update({
//failed order status details
})
.then((countRowsUpdated) => {
console.log(
`Order ${orderId} failure - ${countRowsUpdated} row(s) updated at time ${new Date().toISOString()}`
);
resolve(countRowsUpdated);
});
}
});
};
const run = async function () {
const ordersToBeProcessed = [];
const Order = {};
const orders = await models.orders.findAll(); //database request via sequelize
orders.map(async function (order) {
if (order.action === "entry") {
Order = populateOrderObject(order);
}
if (order.action === "exit") {
try {
currentPosition = await fetchCurrentPosition(); //network request via axios. Cause of the bug. Edited to include try... catch block
Order = populateOrderObject(order,currentPosition);
} catch (error) {
//Update db with details about failed fetch position
await models.orders
.update({
//failed fetch position details including error
})
}
}
ordersToBeProcessed.push(sendOrder(Order));
});
Promise.allSettled(ordersToBeProcessed).then((responses) => {
responses.map((response) => {
console.log(" response: " + response.status + ",value: " + response.value);
});
console.log("processedOrders.length is: " + processedOrders.length);
console.log("Number of responses is: " + responses.length);
if (orders.length === responses.length) {
setTimeout(run,500);
}
});
};
setTimeout(run,500);
这是下面的输出。作为参考,订单361和362是带有order.action ===“ entry”的进入订单,而订单360和364是退出订单:
Order engine started: 2020-10-12T21:22:47.712Z
running orders at time 2020-10-12T21:22:48.232Z
order about to be placed for 361 at time 2020-10-12T21:22:48.302Z
order about to be placed for 362 at time 2020-10-12T21:22:48.302Z
24
order about to be placed for 360 at time 2020-10-12T21:22:48.838Z
order about to be placed for 364 at time 2020-10-12T21:22:48.839Z
order 361 sent to broker at 2020-10-12T21:22:48.909Z
Order 361 success - 1 row(s) updated at time 2020-10-12T21:22:48.918Z
order 362 sent to broker at 2020-10-12T21:22:48.927Z
Order 362 success - 1 row(s) updated at time 2020-10-12T21:22:48.930Z
response: fulfilled,value: 1
response: fulfilled,value: 1
processedOrders.length is: 4
Number of responses is: 2
order 360 sent to broker at 2020-10-12T21:22:49.181Z
Order 360 success - 1 row(s) updated at time 2020-10-12T21:22:49.185Z
order 364 sent to broker at 2020-10-12T21:22:49.185Z
Order 364 success - 1 row(s) updated at time 2020-10-12T21:22:49.197Z
当order.action等于“ exit”时,Promise.allSettled(以及Promise.all)在没有这些退出订单的情况下进行解析。因此,响应中仅包括进入顺序。退出订单最终得以解决,但脚本因未触发条件setTimeout而终止。为了实现在Promise.allSettled.then运行之前解决所有已处理订单的预期目标,我该怎么办?我认为这是问题的根源,我该如何处理退出订单中的额外网络请求?我认为这与事件循环和微任务处理有关,但是我不能从那里继续前进。
解决方法
我该怎么做才能达到在
Promise.allSettled.then
运行之前解决所有已处理订单的预期目标?
将它们放入Promise.allSettled
正在等待的承诺数组中。您在orders
上进行的循环具有一个异步部分,并且在循环后立即调用ordersToBeProcessed
的之后,将退出订单放入Promise.allSettled
数组中。使用map
方法的正确写法是
async function run() {
const orders = await models.orders.findAll(); //database request via sequelize
const ordersToBeProcessed = orders.map(async function (order) {
// ^^^^^^^^^^^^^^^^^^^^^^
const Order = order.action === "entry" ? populateOrderObject(order) :
order.action === "exit" ? populateOrderObject(order,await fetchCurrentPosition()) :
undefined;
return sendOrder(Order);^
// ^^^^^^
});
const responses = await Promise.allSettled(ordersToBeProcessed);
for (const response of responses) {
console.log(" response: " + response.status + ",value: " + response.value);
});
console.log("All " + ordersToBeProcessed.length + "orders got processed");
setTimeout(run,500);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。