San*_*ete 37 asynchronous scala future async-await
我正在学习在Scala中使用async/await.我在https://github.com/scala/async中看过这个
从理论上讲,这段代码是异步的(非阻塞),但它没有并行化:
def slowCalcFuture: Future[Int] = ...
def combined: Future[Int] = async {
await(slowCalcFuture) + await(slowCalcFuture)
}
val x: Int = Await.result(combined, 10.seconds)
Run Code Online (Sandbox Code Playgroud)
而另一个是并行化的:
def combined: Future[Int] = async {
val future1 = slowCalcFuture
val future2 = slowCalcFuture
await(future1) + await(future2)
}
Run Code Online (Sandbox Code Playgroud)
它们之间的唯一区别是使用中间变量.这怎么会影响并行化?
Pat*_*iek 49
由于它与async & awaitC#类似,也许我可以提供一些见解.在C#中Task,可以等待的一般规则应该是"热",即已经运行.我假设它在Scala中是相同的,Future从函数返回的函数不必显式启动,但在被调用后只是"运行".如果不是这样,那么以下是纯粹的(可能不是真的)推测.
让我们分析第一种情况:
async {
await(slowCalcFuture) + await(slowCalcFuture)
}
Run Code Online (Sandbox Code Playgroud)
我们到达那个街区并点击第一个等待:
async {
await(slowCalcFuture) + await(slowCalcFuture)
^^^^^
}
Run Code Online (Sandbox Code Playgroud)
好的,所以我们异步等待计算完成.当它完成后,我们继续分析块:
async {
await(slowCalcFuture) + await(slowCalcFuture)
^^^^^
}
Run Code Online (Sandbox Code Playgroud)
第二个等待,所以我们异步等待第二次计算完成.完成后,我们可以通过添加两个整数来计算最终结果.
正如你所看到的,我们正在一步一步地等待,等待Future它们一个接一个地出现.
我们来看看第二个例子:
async {
val future1 = slowCalcFuture
val future2 = slowCalcFuture
await(future1) + await(future2)
}
Run Code Online (Sandbox Code Playgroud)
好的,所以这是(可能)发生的事情:
async {
val future1 = slowCalcFuture // >> first future is started, but not awaited
val future2 = slowCalcFuture // >> second future is started, but not awaited
await(future1) + await(future2)
^^^^^
}
Run Code Online (Sandbox Code Playgroud)
然后我们正在等待第一个Future,但两个期货目前正在运行.当第一个返回时,第二个可能已经完成(因此我们将立即获得结果)或者我们可能需要等待一段时间.
现在很明显,第二个例子并行运行两个计算,然后等待它们两个完成.两者都准备好后,它会返回.第一个示例以非阻塞方式运行计算,但是按顺序运行.
Mik*_*kha 24
如果有点难以理解,Patryk的答案是正确的.主要的事情,了解有关异步/等待是,它做的只是另一种方式Future的flatMap.幕后没有并发魔法.异步块内的所有电话都是连续的,其中的await实际上不阻止执行的线程,而是包裹异步块的其余部分在关闭,并将其作为一个在完成回调的Future,我们正在等待.所以在第一段代码中,第二次计算直到第一次await完成才开始,因为之前没有人开始它.
| 归档时间: |
|
| 查看次数: |
11831 次 |
| 最近记录: |