一、回调地狱
网上有很多讲解Promise的文章,大都没有讲清楚基本的用法,这里写一篇讲解的更清楚一些。假设有个获取网络数据的函数:$.getJSON( url ,{ }, sucesscallback, failedcallback) ,
参数的含义分别是:url地址,请求参数{},获取成功后的回调,和获取失败后的回调,比如网上的一个例子

apiUserInfo 接口依赖apiToken,apiToken依赖apiKey,以上并没有处理失败的代码,所以看起来是个梯子型状的,否则会是倒金字塔状的,可以想象如果依赖层次过多,代码看起来会是多么的丑陋。
二、使用async 和Promise 解决问题

先来个demo演示,如上图,如果我们有多个异步请求,它们之间还存在依赖关系,可以用如上的两种方法来解决,当然,不限于这两种。如果是网络请求的话,把setTimeout换成fetch就可以了。
为什么在一个Promise的then方法中,又用了一个Promise呢,这是因为想要把setTimeout函中的val传到下一个then去,并且还得等待setTimeout函数执行完。或者直接return setTimeout函数 ?直接return setTimeout 也不行。发现只用Promise实现继发性的多个异步操作时,只能这样做来。
用Generator 实现继发性的多个异步操作时,也就是后来的异步操作依赖前面的异步操作结果,可能的一种形式如下:

这个的不好之处在于,需要控制执行过程,让先执行的yield的返回值,传入到next()参数中,供下一个yield语句使用,co模块实现这个,还用都了thunk函数原理。
综上,还是async最好,直观,还简单。
只用一个Promise 和fetch实现继发性异步控制,也是可以的,如下图

不过这有个要求,就是必须在then中返回Promise版本的fetch,这个本质上跟亮哥写的Promise的setTimeout一样。如上的readFile就是Promise版本的

网友评论