Future/Await和Async/Await有什么区别?

5
在Scala和其他编程语言中,可以使用Futures和Await。(在实际代码中,一个常见的替代方案是使用zip+map而非Await)
def b1() = Future { 1 }
def b2() = Future { 2 }

def a() = Future {
  Await.result(b1(),Duration.inf) + Await.result(b2(),Duration.inf)
}

在JavaScript/Scala中,异步/等待与什么不同?
async function b1() { return 1 }
async function b2() { return 3 }

async function a() { 
  return await b1() + await b2()
}
2个回答

5
在Scala中,"Await.result"函数是"阻塞的",这意味着调用线程将被暂停,直到等待的Future完成,此时它将通过返回值恢复。
在高负载系统中暂停线程可能很昂贵,因为线程上下文必须保存在内存中,并且它可能导致缓存未命中等问题。由于这个原因,在并发编程中阻塞线程被认为是不良实践。
Javascript中的async/await语法是非阻塞的。当一个async函数调用“await”时,它会转换为Future,并放置在执行队列中。当等待的Future完成时,调用函数将被标记为准备好执行,并在稍后的某个时间恢复。重要的区别是在这个模型中不需要暂停任何线程。
有许多库在Scala中实现了async/await语法,包括https://github.com/scala/scala-async 更多阅读
  • 未来与承诺一书由PRASAD、PATIL和MILLER编写,对阻塞和非阻塞操作有很好的介绍。

感谢@Rich,Scala的asyn/await库是否以相同方式工作,但将Futures放入队列并恢复函数?如果我理解正确,asyn/await会阻塞函数的执行,但不会通过阻塞线程来占用它。async/await更像Go中的goroutines或green threads吗? - KingOfCoders
避免阻塞的主要原因是死锁的危险,性能不是那么重要。 - Tim
1
@Tim,我不认为那是正确的。也许你在考虑“非阻塞”锁定冲突解决算法的意义?我认为这与此处讨论的“非阻塞”是完全不同的概念。请参见https://en.wikipedia.org/wiki/Non-blocking_algorithm和“不要与...混淆”的链接。我认为,假设你翻译了独占锁,异步/等待代码具有与同步代码完全相同的死锁属性。无论如何,异步代码的动机与此问题无关。如果我的回答中加入了它,让你感到困惑,我很抱歉。 - Rich
1
@StephanSchmidt,是的,Scala的async/await库的工作方式类似于Javascript中的async/await。我想我知道你在“绿色线程”评论中的意思,但是绿色线程与本机线程实际上与Futures和async/await之间的编程语法区别是正交的。不过,这个评论框太小了,无法进行讨论 :-) 请参见https://en.wikipedia.org/wiki/Green_threads - Rich
@Rich 谢谢你的解释! - KingOfCoders
显示剩余2条评论

1
Await 是阻塞的,而 async 是非阻塞的。Await 在当前线程等待任务完成,而 async 不会阻塞当前线程,而是在后台运行。
我对 JavaScript 没有任何了解。在 Scala 中,来自 scala.concurrent 包的 Await 用于阻塞主线程。还有另一个名为 scala-async 的库,可以在 async 块中使用 await
如果您正在使用 scala-async,则需要在 async 中调用 await。

await b1() 应该是阻塞的,在由异步函数 a() 运行的线程中,不是吗?JavaScript 在这里使用绿色线程,例如在 Node 中吗? - KingOfCoders

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接