使用Promise.all在数组中执行promise会破坏它们 [英] Executing promises in array with Promise.all breaks them
问题描述
我有一个userIds数组,我在getOrdersByUserId()中使用它来获取这些用户在特定月份下的订单:
I have an array of userIds that I use in getOrdersByUserId() to get the orders placed by these users for a specific month:
function getOrdersByUserId(userId, month = 4) {
const apiService = new ApiService();
return apiService.getOrdersList(`?OrderingUser=${userId}`)
.then(orders => {
const monthOrders = orders.filter(order => new Date(order.FromTime)
.getMonth() === month);
return monthOrders;
});
}
这是ApiService中的getOrdersList():
Here's getOrdersList() in ApiService:
getOrdersList(queryString = '') {
return httpsRequest.createRequest(this.URL.ordersList + queryString, {}, this.requestHeaders, 'GET')
.then(result => JSON.parse(result).Records);
}
httpsRequest.createRequest返回一个使用API响应解析的承诺(I如有必要,也可以共享该代码)。
httpsRequest.createRequest returns a promise that resolves with the response from the API (I can share that code too if necessary).
当我用8个userIds测试getOrdersByUserId()时,我每次都得到正确的记录。当我将这些调用放入一个promise链并使用Promise.All()执行它们时,这会中断。我在这个答案的帮助下写了下面的代码:等待每个人内部承诺完成
When I test getOrdersByUserId() with 8 userIds I have, I get the correct records every time. Where this breaks is when I put these calls into a promise chain and execute them with Promise.All(). I wrote the below code with help from this answer: Wait for forEach with a promise inside to finish
const promises = userIds.map(userId => {
return getOrdersByUserId(userId, month)
.then(orders => {
return orders;
});
});
Promise.all(promises).then(results => {
console.log(results);
}).catch(err => {
console.log(err);
});
使用8个userIds进行测试我得到此错误四到五次:
Testing with the 8 userIds I get this error four or five times:
(node:1) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): SyntaxError: Unexpected end of JSON input
经过大量的控制台日志记录后,当httpsRequest.createRequest()给出的结果为空字符串而不是来自API的JSON响应。那么为什么所有这些具有相同userIds的调用都会单独工作,但在promise链中执行时会中断?我该如何解决这个问题?
After a lot of console logging it seems that this error occurs when httpsRequest.createRequest() gives a result that is an empty string, instead of a JSON response from the API. So why would all of these calls with the same userIds work individually, but break when executed in a promise chain? How can I resolve this?
推荐答案
你有一个常见的误解:你没有执行承诺。 Promise.all
不会运行任何内容。承诺只是一种观察操作的方法,可以知道它何时完成以及它是否有效。
You have a common misunderstanding: You don't execute promises. Promise.all
doesn't "run" anything. A promise is just a means of watching an operation to know when it's done and whether it worked or failed.
在您的情况下,操作由<$ c $启动c> apiService.getOrdersList ,一旦你调用它。
In your case, the operations are started by apiService.getOrdersList
, as soon as you call it.
你所看到的暗示
-
API服务不喜欢您同时发送8个请求(可能是速率限制),
The API service doesn't like you sending it eight simultaneous requests (perhaps it rate-limits), and
来自API服务的promise使用无效JSON的值解析,而不是在它无法处理#1时拒绝(这是不幸的,它应该拒绝,而不是解析)。
The promise from the API service resolves with a value that isn't valid JSON rather than rejecting when it can't handle #1 (which is unfortunate, it should reject, not resolve).
使用 Promise.all
没有什么可以打破这些操作。但显然,并行运行其中八个操作。
Nothing about using Promise.all
breaks these operations. But apparently, running eight of these operations in parallel breaks.
你可以连续运行它们(一个接一个):
You could run them in series (one after another):
userIds.reduce((p, userId, index) => {
return p.then(results => {
return getOrdersByUserId(userId, month)
.then(orders => {
results[index] = orders;
return results;
});
});
}, Promise.resolve([]))
.then(results => {
// `results` is an array of results, in the same order as `userIds`
})
.catch(err => {
console.log(err);
});
每次拨打 getOrdersByUserId
等待之前的一个完成;最终结果是与 userIds
数组的顺序相同的结果数组。
Each call to getOrdersByUserId
waits for the previous one to complete; the final result is an array of results in the same order as the userIds
array.
这篇关于使用Promise.all在数组中执行promise会破坏它们的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!