在Javascript里面,有一个超级重要的概念就是非同步,这也是刚入门的时候最容易搞混、忘记的观念
ES6原生支援了,搭配使用效果更佳,而ES7甚至支援了的语法
我觉得这算是一个演进的过程,让程式架构越来越好、可读性越来越高
所以要讲解这些新的东西,就先从最基本的callback开始吧
现在假设我们有三个api
第一个是抓取文章列表的api
第二个是给文章id, 抓取文章内容的api
第三个是给作者id, 返回作者资讯的api
现在想要达成的功能是:抓取最新的一篇文章的作者信箱流程就是:抓文章列表->抓文章资讯->抓作者实作成code就像这样
相信这样子的code大家应该都不陌生,但是这样会有一个缺点就是我们俗称的callback hell,这样一层一层一层的实在是有点丑那该怎么办呢?
有种东西叫做,就这样出现了先来个实际范例再来讲解吧!
是一个物件,有三种状态,等待中(pending)、完成(resolve or fulfilled)跟失败(reject)
在上面的范例中,我们把那三个函数的callback function拿掉了,取而代之的是返回一个Promise物件
原本应该是要出现的地方,变成了这样有什么好处呢?看我们最上面呼叫这些函式的地方,原本的callback hell不见了,被我们压平了如果看的不是很懂,就先从最基本的,呼叫一个Promise开始
你可以在物件后面加上,就会是这个Promise跑完之后的结果
假如在里面另一个Promise物件,就可以不断串接使用
像是这样
有了Promise的这个特性,就可以避免掉callback hell
如果我们加上ES6的arrow function,甚至可以简化成这样
单纯运用Promise的范例就到这边为止,其实到这边语法已经满简单的了,而且有了arrow function以后,可读性有变得比较好,但是看到一堆总是觉得有点碍眼
那接下来还有什么呢?
ES6里面多了一个Generator,
接着就要利用Generator的特性,来写出超级像同步但其实是非同步的代码
仔细看这个generator,利用的特性,会先执行右边的程式码,等待下一次的呼叫并且赋值给左边
所以我们可以在里面的事件呼叫,就会把回传值丢给这个变数
如果觉得这样有点难懂,可以先换成只有一层的
让我们再回来看看上面那段代码的上半部
有没有觉得,跟同步的程式码很像?只要把拿掉的话,根本就一模一样对吧!
这就是generator的精髓所在了:用很像同步的语法,但其实是非同步
那再来看看下半部
很容易可以发现下半部的语法很固定,并且容易找出规律而且根本就是个递回
所以可以用一个函式包住,处理更多general的case
tj做的co模组就是在做差不多的事情,只是做得更多了
但原理跟我们上面写的很类似,就是把一个generator包起来写一个自动执行器
最后,终于要讲到标题上的最后一个东西了:
这是什么?先来看code
这段code跟之前的差别在于
变成
变成
就这两个点而已
然后你会发现,就这样就结束了
不必用其他模组,不必自己写递回执行器
这就是async的语法,其实就是把那些自动执行写好而已,但是这样的语法让我们方便许多
而其实这个语法是在ES7才有计画引入的,
好消息是,我们上面有关ES6的code都是通过这个library转换成ES5的语法
而他有个实验性功能的地方,其中就有包含
而是在,NOTE: Stage 2 and above are enabled by default.
什么参数都不用调整就自动帮你开启了,真是可喜可贺
当初刚接触ES6时,一下子接触到一堆眼花撩乱的东西,每个再继续深入下去都是一门学问而且我在之前都是纯粹用callback(因为层级不多所以还好),偶尔用一下( node的library,跟上面的不一样)
所以我觉得最好了解的方式,就是从最基础的callback开始,慢慢进步到promise,再进步到generator,最后才是
才能懂得为什么会有这些东西的出现
如果有哪些地方有讲错,还麻烦在下方留个言
感谢
领取专属 10元无门槛券
私享最新 技术干货