什么是异步

说到异步,就肯定得提一下同步,根据各种说法,可以总结出来:

  • 同步:任务调用阻塞当前任务
  • 异步:任务调用不阻塞当前任务

这里我们举一个搬砖的栗子,假设有一堆砖头,需要搬到二楼.

一部分人会选择自己搬,于是搬了半天,期间啥事也没干,等搬完了,才能回家洗澡吃饭大游戏,这是同步。

另一部分人,会选择花点钱雇个人帮他搬,自己则去逍遥自在,等人家搬完了,打个电话回来验收一下,跟工头汇报一下就好了。这是异步。

在程序中,对应的故事:

假设我要复制一个文件,可以同步,也可以异步:

  • 同步:开一个InputStream,再开一个OutputStream,然后吭哧吭哧地复制,完了再继续做其他事。
  • 异步:开一个线程,然后在提交一个复制的任务给线程去运行,自己该干啥干啥去,然后等复制完了,回调回来,再去处理复制完后的事情。

为什么要有异步

对于客户端、前端等等,主要还是一个用户体验的问题,假设都是同步地处理任务,那么程序基本上是一会儿就要卡一会儿,下载个文件卡一会儿,读取个文件卡一会儿。因此我们就引入了异步编程,可以在处理耗时任务的时候,程序可以继续做其他事情,比如下载文件的时候还可以继续刷网页。

异步与多线程的关系

异步一定要多线程吗?我认为是的。

因为线程本身是CPU调度的最小单元,假设我们完全就只有一个线程,那执行其他任务时,当前任务必然就不能执行了,也就是同步了。

有些旁友会说,Js和Dart是单线程模型,但是他们也支持异步啊。是的没错,他们确实是单线程模型,也确实是支持异步,关键就在于,他们的异步操作,是由引擎去维护执行的,执行完了再告诉我们,并不是真的所有的操作都在一个线程里面执行。关于这个,具体可以参考: https://dev.to/steelvoltage/if-javascript-is-single-threaded-how-is-it-asynchronous-56gd

异步与回调的关系

先问两个问题:

  1. 回调一定是异步吗
  2. 异步一定要回调吗

第一个问题:No,回调和异步没有必然联系,关键看回调前的操作是同步执行的还是异步执行的,如果没有在其他线程执行,那么只是回调只是相当于执行完任务后,再执行回调方法,本质上一直都是一条线。

第二个问题: No,异步是执行任务的一种方式,只有我们需要结果,才需要回调,否则是不需要的。即使是需要结果,现代语言也提供了例如Future、async、 await等方式去处理结果,并不一定需要回调。

总结

以上是本人对异步的一点想法,水平有限,如有问题,烦请指出,避免误导他人。

参考