对象键的异步/等待分配:它是并发的吗?
Posted
技术标签:
【中文标题】对象键的异步/等待分配:它是并发的吗?【英文标题】:Async / await assignment to object keys: is it concurrent? 【发布时间】:2017-10-17 16:02:38 【问题描述】:我知道这样做:
const resultA = await a()
const resultB = await b()
// code here
有效
a().then( resultA =>
b().then( resultB =>
// code here
)
)
基本上,a() 运行 然后 b() 运行。我嵌套它们以表明 resultA 和 resultB 都在我们的范围内;但是这两个功能都没有立即运行。
但是这个呢:
const obj =
result1: await a(),
result2: await b()
a() 和 b() 是否同时运行?
供参考:
const asyncFunc = async (func) => await func.call()
const results = [funcA,funcB].map( asyncFunc )
我知道这里funcA
和funcB
会同时运行。
奖金:
你将如何表示对象分配
const obj =
result1: await a(),
result2: await b()
使用then
/回调?
更新:
@Bergi 在这个答案中是正确的,这是按顺序发生的。要分享一个很好的解决方案,让一个对象同时进行这项工作,而不必将数组中的对象拼凑在一起,也可以使用Bluebird
,如下所示
const obj2 = Bluebird.props(obj)
http://bluebirdjs.com/docs/api/promise.props.html
【问题讨论】:
您的“供参考”示例存在语法错误(因此具有误导性)。如果使用await
,则必须使箭头函数async
,然后很明显它们可能会同时运行,因为它们是单独的函数评估。
感谢您的理解,已更正。
请注意,JS函数可能会触发异步进程并发运行,但JS函数本身并不是多线程同时执行意义上的并发运行。
【参考方案1】:
不,每个await
都会停止执行,直到承诺完成,即使是在表达式中。它们是否恰好是同一语句的一部分并不重要。
如果你想并行运行它们,并且只等待一次它们的结果,你必须使用await Promise.all(…)
。在你的情况下,你会写
const [result1, result2] = await Promise.all([a(), b()]);
const obj = result1, result2;
您将如何使用
then
/ 回调来表示对象分配?
每个等待值都有临时变量。每个await
转换为一个then
调用:
a().then(tmp1 =>
return b().then(tmp2 =>
const obj =
result1: tmp1,
result2: tmp2
;
return …
);
)
如果我们想学究气,就必须拆开对象创建:
const tmp0 = ;
a().then(tmp1 =>
tmp0.result1 = tmp1;
return b().then(tmp2 =>
tmp0.result2 = tmp2;
const obj = tmp0;
return …
);
)
【讨论】:
你是对的!我刚刚写完测试代码来尝试使用 setTimeout 上面的代码,它确实是按顺序运行的。【参考方案2】:a() 和 b() 是否同时运行?
不,它们按顺序运行。
相当于
a()
.then(result1 => b())
.then(result2 => (result1, result2))
【讨论】:
以上是关于对象键的异步/等待分配:它是并发的吗?的主要内容,如果未能解决你的问题,请参考以下文章