我有一个包含5个项目的对象,每个项目都会发送一次HTTP请求3次。 我将其保存在
var promise
var promise1
var promise2
最后,我将使用以下方式解决(尝试)诺言
Promise.all([promise, promise1, promise2]]
然后将数据发送到回调函数。
我正在使用array.map()在该阵列上执行任务,所有请求和Promise.all都在其中发生。
在发送回调函数中的数据之前,如何等待直到完成全部请求并完成了promise?
async function requestJahrStatistic(jahreStatistic, callback){
Promise.all(
jahreStatistic.map(async (item) => {
var periods = getReportingPeriod(item.period);
connection.statistic_id = item.statistic_id;
connection.reporting_period = periods.prevYear;
var promise = new Promise(function(resolve, reject) {
sendHTTPRequest(item, function(result) {
resolve(result);
});
});
connection.reporting_period = periods.actualYear;
var promise1 = new Promise(function(resolve, reject) {
sendHTTPRequest(item, function(result) {
resolve(result);
});
});
connection.reporting_period = periods.nextYear;
var promise2 = new Promise(function(resolve, reject) {
sendHTTPRequest(item, function(result) {
resolve(result);
});
});
Promise.all([promise, promise1, promise2]).then(async resolved => {
var res = await resolved
return res
});
})
).then(async resolved =>{
var resp = await resolved;
callback(resp)
});
}
这是我在写问题之前最后尝试的一件事
答案 0 :(得分:1)
该代码存在几个问题:
requestJahrStatistic
如果通过调用回调报告其结果,则不应为async
您可以在几个地方使用此模式:
.then(async resolved => {
var res = await resolved
return res
});
这毫无用处(除非...请参阅#5),并且可以完全删除。
没有理由将map
回调设为async
,因为您没有在其中使用await
。
您正在重复将sendHTTPRequest
包装在承诺中的逻辑,并且无法处理其中的错误。不要重复自己,为此做一个函数。
HTTP请求似乎使用了connection.statistic_id
和connection.reporting_period
。他们不应该这样,那是远距离的诡异动作。 :-)但是,如果它们是无,则可以并行执行,因为您必须等待使用给定的statistic_id
和reporting_period
完成的请求,然后才能开始下一个。
您没有处理错误。
如果我假设HTTP请求使用connection.reporting_period
,则意味着它们不能重叠,因此这两个请求不能并行进行,因此不能使用Promise.all
。您将需要以下内容:
如果HTTP请求未使用connection.reporting_period
,则可以全部并行进行:
function sendHTTPRequestP(item) {
return new Promise((resolve, reject) => {
sendHTTPRequest(item, result => {
if (/*an error occurred*/) {
reject(new Error(/*...*/));
} else {
resolve(result);
}
});
})
}
// Completely serial because of spooky action at a distance with
// `connection.statistic_id` and `connection.reporting_period`
function requestJahrStatistic(jahreStatistic, callback) {
Promise.resolve(async () => {
const results = [];
for (const item of jahreStatistic) {
const periods = getReportingPeriod(item.period);
connection.statistic_id = item.statistic_id;
connection.reporting_period = periods.prevYear;
const result1 = await sendHTTPRequestP(item);
connection.reporting_period = periods.actualYear;
const result2 = await sendHTTPRequestP(item);
connection.reporting_period = periods.nextYear;
const result3 = await sendHTTPRequestP(item);
results.push([result1, result2, result3]);
}
return results;
})
.then(callback)
.catch(error => {
// Handle/report error, call `callback` with the appropriate error flag
});
}
或者类似的东西。请注意,callback
将收到一个数组数组。外部数组的条目将与jahreStatistic
一样多;这些条目中的每一个都是三个HTTP调用结果的数组。
如果您可以更改某些内容,以便每个操作都可以接受参数而不是采取一些诡异的操作(我发现sendHTTPRequest已经具有item
,因此可以从中获取statistic_id
,所以我们只需传递period
),则可以使事情平行:
function sendHTTPRequestP(item, reporting_period) {
return new Promise((resolve, reject) => {
sendHTTPRequest(item, reporting_period, result => {
if (/*an error occurred*/) {
reject(new Error(/*...*/));
} else {
resolve(result);
}
});
})
}
function requestJahrStatistic(jahreStatistic, callback){
Promise.all(
jahreStatistic.map((item) => {
const periods = getReportingPeriod(item.period);
return Promise.all([
sendHTTPRequestP(item, periods.prevYear),
sendHTTPRequestP(item, periods.actualYear),
sendHTTPRequestP(item, periods.nextYear)
]);
})
)
.then(callback)
.catch(error => {
// Handle/report error, call `callback` with the appropriate error flag
});
}
或者类似的东西。