知其然知其所以然,首先了解三个概念:
1.什么是同步?
所谓同步,就是在发出一个"调用"时,在没有得到结果之前,该“调用”就不返回。但是一旦调用返回,就得到返回值了。换句话说,就是由“调用者”主动等待这个“调用”的结果。此调用执行完之前,阻塞之后的代码执行。
2.什么是异步?
"调用"在发出之后,这个调用就直接返回了,没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是在"调用"发出后,"被调用者"通过状态、通知来通知调用者,或通过回调函数处理这个调用。异步调用发出后,不影响后面代码的执行。
3.JavaScript 中为什么需要异步?
首先我们知道JavaScript是单线程的(即使新增了webworker,但是本质上JS还是单线程)。同步代码意味着什么呢?意味着有可能会阻塞,当我们有一个任务需要时间较长时,如果使用同步方式,那么就会阻塞之后的代码执行。而异步则不会,我们不会等待异步代码的执行,继续执行异步任务之后的代码。
概念了解完了,我们就要进入今天的正题了。首先大家思考一下:平时在工作中,主要使用了哪些异步解决方案,这些异步方案有什么优缺点?
异步最早的解决方案是回调函数,如事件的回调,setInterval/setTimeout中的回调。但是回调函数有一个很常见的问题,就是回调地狱的问题(稍后会举例说明);
为了解决回调地狱的问题,社区提出了Promise解决方案,ES6将其写进了语言标准。Promise一定程度上解决了回调地狱的问题,但是Promise也存在一些问题,如错误不能被try catch,而且使用Promise的链式调用,其实并没有从根本上解决回调地狱的问题,只是换了一种写法。
ES6中引入 Generator 函数,Generator是一种异步编程解决方案,Generator 函数是协程在 ES6 的实现,最大特点就是可以交出函数的执行权,Generator 函数可以看出是异步任务的容器,需要暂停的地方,都用yield语句注明。但是 Generator 使用起来较为复杂。
ES7又提出了新的异步解决方案:async/await,async是 Generator 函数的语法糖,async/await 使得异步代码看起来像同步代码,异步编程发展的目标就是让异步逻辑的代码看起来像同步一样。
回调函数 ---> Promise ---> Generator ---> async/await.
1.callback
//node读取文件