在kotlinx。协程库,您可以使用启动(使用join)或异步(使用await)启动新的协程。它们之间的区别是什么?


当前回答

launch is used to fire and forget coroutine. It is like starting a new thread. If the code inside the launch terminates with exception, then it is treated like uncaught exception in a thread -- usually printed to stderr in backend JVM applications and crashes Android applications. join is used to wait for completion of the launched coroutine and it does not propagate its exception. However, a crashed child coroutine cancels its parent with the corresponding exception, too. async is used to start a coroutine that computes some result. The result is represented by an instance of Deferred and you must use await on it. An uncaught exception inside the async code is stored inside the resulting Deferred and is not delivered anywhere else, it will get silently dropped unless processed. You MUST NOT forget about the coroutine you’ve started with async.

其他回答

both coroutine builders namely launch and async are basically lambdas with receiver of type CoroutineScope which means their inner block is compiled as a suspend function, hence they both run in an asynchronous mode AND they both will execute their block sequentially. The difference between launch and async is that they enable two different possibilities. The launch builder returns a Job however the async function will return a Deferred object. You can use launch to execute a block that you don't expect any returned value from it i.e writing to a database or saving a file or processing something basically just called for its side effect. On the other hand async which return a Deferred as I stated previously returns a useful value from the execution of its block, an object that wraps your data, so you can use it for mainly its result but possibly for its side effect as well. N.B: you can strip the deferred and get its value using the function await, which will block the execution of your statements until a value is returned or an exceptions is thrown! You could achieve the same thing with launch by using the function join() both coroutine builder (launch and async) are cancelable. anything more?: yep with launch if an exception is thrown within its block, the coroutine is automatically canceled and the exceptions is delivered. On the other hand, if that happens with async the exception is not propagated further and should be caught/handled within the returned Deferred object. more on coroutines https://kotlinlang.org/docs/tutorials/coroutines/coroutines-basic-jvm.html https://www.codementor.io/blog/kotlin-coroutines-6n53p8cbn1

launch is used to fire and forget coroutine. It is like starting a new thread. If the code inside the launch terminates with exception, then it is treated like uncaught exception in a thread -- usually printed to stderr in backend JVM applications and crashes Android applications. join is used to wait for completion of the launched coroutine and it does not propagate its exception. However, a crashed child coroutine cancels its parent with the corresponding exception, too. async is used to start a coroutine that computes some result. The result is represented by an instance of Deferred and you must use await on it. An uncaught exception inside the async code is stored inside the resulting Deferred and is not delivered anywhere else, it will get silently dropped unless processed. You MUST NOT forget about the coroutine you’ve started with async.

除了其他很好的答案,对于熟悉Rx和进入协同程序的人来说,async返回一个类似于Single的Deferred,而launch返回一个更类似于Completable的Job。您可以.await()阻塞并获取第一个的值,.join()阻塞直到Job完成。

Async和Launch,两者都用于创建在后台运行的协程。几乎在任何情况下,人们都可以使用它们中的任何一个。

tl;博士版:

当你不关心任务的返回值,只想运行它时,你可以使用Launch。如果你需要任务/协程的返回类型,你应该使用async。

Alternate: However, I feel the above difference/approach is a consequence of thinking in terms of Java/one thread per request model. Coroutines are so inexpensive, that if you want to do something from the return value of some task/coroutine(lets say a service call) you are better off creating a new coroutine from that one. If you want a coroutine to wait for another coroutine to transfer some data, I would recommend using channels and not the return value from Deferred object. Using channels and creating as much number of coroutines as required, is the better way IMO

详细的回答:

唯一的区别是返回类型和它提供的功能。

Launch返回Job, Async返回Deferred。有趣的是,Deferred扩展了Job。这意味着它必须在Job之上提供额外的功能。Deferred是在T是返回类型的地方参数化的类型。因此,Deferred对象可以从async方法执行的代码块中返回一些响应。

附注:我之所以写下这个答案,是因为我在这个问题上看到了一些事实上不正确的答案,我想为大家澄清这个概念。另外,在我自己做一个宠物项目时,由于之前有Java背景,我也遇到过类似的问题。

启动/异步没有结果

用在不需要结果的时候, 不要阻塞被调用的代码, 按顺序运行

Async for result

当需要等待结果时,可以并行运行 效率, 阻塞被调用的代码, 并发运行