最近在用node.js写一个工具,发现自己对Promise的模式还是不太了解,于是打算重温《深入浅出node.js》,不过精读的时候发现该书没有随书代码的下载,而且书中关于Promise的部分代码交代不够清楚,可能影响读者理解,本人花了一些时间将代码整理出来,建议读者对照书籍查看。
1.Promise/A
不清楚Promise模式定义的同学请自行百度,书中使用Promise/A模式以点带面介绍Promise。在介绍完Promise/A的抽象定义后,通过继承node的events模块来完成了一个简单的实现。
需要注意两点 :
1)Promise继承自events,其中继承的方式采用了寄生组合式继承(详见《Javascript高级程序设计》第三版)
2)then方法继续返回Promise对象,以实现链式调用
为了完成整个流程,还需要触发执行这些回调函数的地方,实现这些功能的对象通常被称为Deferred,即延迟对象
现在我们对一个典型的响应对象进行封装
我们将其改造为Promise/A模式
原书在18行代码出有错误,已调整。。从上面的代码可以看出,Deferred主要是用于内部,用于维护异步模型的状态;Promise则作用于外部,通过then()方法暴露给外部以添加自定义逻辑。
2.Promise中的多异步协作
在Promise的介绍中说过,主要解决的是单个异步操作中存在的问题。回到我们的难点,当我们需要处理多个异步调用时,又该如何处理呢?
这里我们保持Promise代码不变
Deferred代码增加了all()方法,all()方法将两个单独的Promise重新抽象组合成一个新的Promise
我们以多次访问文件为例,只有所有异步操作成功,这个异步操作才算成功,一旦其中一个异步操作失败,整个异步操作就失败。
3.Promise的同步操作
在Node中,网络库是完全异步的,无法在编程层面实现像其他语言那般的同步调用。因此解决同步调用的代码可能就变成了
理想的编程体验应当是前一个的调用结果作为下一个调用的开始,是传说中的链式调用,下面进行改造
Promise代码:
Deferred代码:
调用代码:
可以看到最后一个then的调用主体已经完全转交给了readFile2中的promise对象,通过这种方式,我们完全可以写出更优雅的同步代码。