java 异步的await_并行调用异步/等待功能

据我了解,在ES7 / ES2016中,在代码中放置多个await的工作方式类似于将带有.then()的承诺链接在一起,这意味着它们将一个接一个地执行而不是并行执行。 因此,例如,我们有以下代码:

await someCall();

await anotherCall();

我是否正确理解只有在someCall()完成后才会调用anotherCall() ? 并行调用它们的最优雅方式是什么?

我想在Node中使用它,所以也许有一个异步库解决方案?

编辑:我不满意此问题提供的解决方案: 减速是由于异步生成器中非并行等待promise ,因为它使用生成器,并且我询问的是更通用的用例。

#1楼

您可以在Promise.all()上等待:

await Promise.all([someCall(), anotherCall()]);

要存储结果:

let [someResult, anotherResult] = await Promise.all([someCall(), anotherCall()]);

#2楼

TL; DR

使用Promise.all进行并行函数调用时,发生错误时答案行为不正确。

首先,一次执行所有异步调用并获取所有Promise对象。 其次,对Promise对象使用await 。 这样,当您等待第一个Promise解决其他异步调用时,仍在进行中。 总体而言,您只会等待最慢的异步调用时间。 例如:

// Begin first call and store promise without waiting

const someResult = someCall();

// Begin second call and store promise without waiting

const anotherResult = anotherCall();

// Now we await for both results, whose async processes have already been started

const finalResult = [await someResult, await anotherResult];

// At this point all calls have been resolved

// Now when accessing someResult| anotherResult,

// you will have a value instead of a promise

JSbin示例: http ://jsbin.com/xerifanima/edit?js,console

注意: await调用是在同一行还是在不同的行上都没有关系,只要第一个await调用发生在所有异步调用之后。 请参阅JohnnyHK的评论。

更新:这个回答有错误不同时间处理根据@ BERGI的答案 ,如发生错误时不会抛出了错误,但所有的承诺都执行之后。 我将结果与[result1, result2] = Promise.all([async1(), async2()])的技巧进行比较: [result1, result2] = Promise.all([async1(), async2()]) ,检查以下代码片段

const correctAsync500ms = () => { return new Promise(resolve => { setTimeout(resolve, 500, 'correct500msResult'); }); }; const correctAsync100ms = () => { return new Promise(resolve => { setTimeout(resolve, 100, 'correct100msResult'); }); }; const rejectAsync100ms = () => { return new Promise((resolve, reject) => { setTimeout(reject, 100, 'reject100msError'); }); }; const asyncInArray = async (fun1, fun2) => { const label = 'test async functions in array'; try { console.time(label); const p1 = fun1(); const p2 = fun2(); const result = [await p1, await p2]; console.timeEnd(label); } catch (e) { console.error('error is', e); console.timeEnd(label); } }; const asyncInPromiseAll = async (fun1, fun2) => { const label = 'test async functions with Promise.all'; try { console.time(label); let [value1, value2] = await Promise.all([fun1(), fun2()]); console.timeEnd(label); } catch (e) { console.error('error is', e); console.timeEnd(label); } }; (async () => { console.group('async functions without error'); console.log('async functions without error: start') await asyncInArray(correctAsync500ms, correctAsync100ms); await asyncInPromiseAll(correctAsync500ms, correctAsync100ms); console.groupEnd(); console.group('async functions with error'); console.log('async functions with error: start') await asyncInArray(correctAsync500ms, rejectAsync100ms); await asyncInPromiseAll(correctAsync500ms, rejectAsync100ms); console.groupEnd(); })();

#3楼

我投赞成票:

await Promise.all([someCall(), anotherCall()]);

请注意调用函数的那一刻,它可能会导致意外的结果:

// Supposing anotherCall() will trigger a request to create a new User

if (callFirst) {

await someCall();

} else {

await Promise.all([someCall(), anotherCall()]); // --> create new User here

}

但是跟随总是触发创建新用户的请求

// Supposing anotherCall() will trigger a request to create a new User

const someResult = someCall();

const anotherResult = anotherCall(); // ->> This always creates new User

if (callFirst) {

await someCall();

} else {

const finalResult = [await someResult, await anotherResult]

}

#4楼

更新:

原始答案很难(在某些情况下是不可能)正确处理承诺拒绝。 正确的解决方案是使用Promise.all :

const [someResult, anotherResult] = await Promise.all([someCall(), anotherCall()]);

原始答案:

只需确保在等待其中一个函数之前调用这两个函数:

// Call both functions

const somePromise = someCall();

const anotherPromise = anotherCall();

// Await both promises

const someResult = await somePromise;

const anotherResult = await anotherPromise;

#5楼

我创建了一个辅助函数waitAll,可能会使它更甜。 目前,它仅适用于nodejs , 不适用于浏览器chrome。

//const parallel = async (...items) => {

const waitAll = async (...items) => {

//this function does start execution the functions

//the execution has been started before running this code here

//instead it collects of the result of execution of the functions

const temp = [];

for (const item of items) {

//this is not

//temp.push(await item())

//it does wait for the result in series (not in parallel), but

//it doesn't affect the parallel execution of those functions

//because they haven started earlier

temp.push(await item);

}

return temp;

};

//the async functions are executed in parallel before passed

//in the waitAll function

//const finalResult = await waitAll(someResult(), anotherResult());

//const finalResult = await parallel(someResult(), anotherResult());

//or

const [result1, result2] = await waitAll(someResult(), anotherResult());

//const [result1, result2] = await parallel(someResult(), anotherResult());

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值