Promise 规范与原理解析 | 京东物流技术团队

摘要
Promise 对象用于清晰的处理异步任务的完成,返回最终的结果值,本次分享主要介绍 Promise 的基本属性以及 Promise 内部的基础实现,能够帮我们更明确使用场景、更快速定位问题。
Promise 出现的原因
首先我们先来看一段代码:异步请求的层层嵌套
或者我们可以将上面的代码优化为下面这样
由上面的两种写法的请求可见,在 promise 之前,为了进行多个异步请求并且依赖上一个异步请求的结果时,我们必须进行层层嵌套,大多数情况下,我们又对异步结果进行数据处理,这样使得我们的代码非常难看,并且难以维护,这就形成了回调地狱,由此 Promise 开始出现了。
回调地狱缺点
- 代码臃肿 
- 可读性差 
- 耦合性高 
- 不好进行异常处理 
Promise 的基本概念
含义
- ES6 将其写进了语言标准里统一了用法,是一个构造函数,用来生成 Promise 实例 
- 参数为一个执行器函数(执行器函数是立即执行的),该函数有两个函数作为参数,第一个参数是成功时的回调,第二个参数是失败时的回调 
- 函数的方法有 resolve(可以处理成功和失败)、reject(只处理失败)、all 等方法 
- then、catch、finally 方法为 Promise 实例上的方法 
状态
- pending --- 等待状态 
- Fulfilled --- 执行状态 (resolve 回调函数,then) 
- Rejected --- 拒绝状态 (reject 回调函数,catch) 
- 状态一旦改变就不会再变,状态只可能是两种改变,从 pending->Fulfilled,pending->Rejected 
- 有两个关键的属性:PromiseState --- 状态改变,PromiseResult --- 结果数据改变 
 
 特点
- 错误信息清晰定位:可以在外层捕获异常信息(网络错误、语法错误都可以捕获),有“冒泡”性质,会一直向后传递,直到被捕获,所以在最后写一个 catch 就可以了 
- 链式调用:每一个 then 和 catch 都会返回一个新的 Promise,把结果传递到下一个 then/catch 中,因此可以进行链式调用 --- 代码简洁清晰 
结果由什么决定
resolve
- 如果传递的参数是非 Promise 类型的对象,则返回的结果是成功状态的 Promise 对象,进入下一个 then 里面 
- 如果传递的参数是 Promise 类型的对象,则返回的结果由返回的 Promise 决定,如果返回的是 resolve 则是成功的状态,进入下一个 then 里,如果返回的是 reject 则是失败的状态,进入下一个 catch 里 
reject
- 如果传递的参数是非 Promise 类型的对象,则返回的结果是拒绝状态的 Promise 对象,进入下一个 catch 里面或者是下一个 then 的第二个参数 reject 回调里面 
- 如果传递的参数是 Promise 类型的对象,则返回的结果由返回的 Promise 决定,如果返回的是 resolve 则是成功的状态,进入下一个 then 里,如果返回的是 reject 则是拒绝的状态,进入下一个 catch 里面或者是下一个 then 的第二个参数 reject 回调里面 
这在我们自己封装的 API 里面也有体现:为什么 code 为 1 时都是 then 接收,其他都是 catch 接收,就是因为在 then 里面也就是 resolve 函数中对 code 码进行了判断,如果是 1 则返回 Promise.resolve(),进入 then 里处理,如果是非 1 则返回 Promise.reject(),进入 catch 里处理。
流程图
 
 简单使用
手写实现简单的 Promise
通过上面的回顾,我们已经了解了 Promise 的关键属性和特点,下面我们一起来实现一个简单的 Promise 吧
针对 resolve 中返回 Promise 对象时的内部执行顺序
 
 总结
以上就是我们常用的 Promise 基础实现,在实现过程中对比了 Promise 和函数嵌套处理异步请求的优缺点,Promise 仍存在缺点,但是的确方便很多,同时更清晰的理解到错误处理如何进行异常穿透的,也能帮助我们更规范的使用 Promise 以及快速定位问题所在。
作者:京东物流 孙琦
来源:京东云开发者社区 自猿其说 Tech 转载请注明来源
版权声明: 本文为 InfoQ 作者【京东科技开发者】的原创文章。
原文链接:【http://xie.infoq.cn/article/558342573da838270da0d5ac4】。文章转载请联系作者。











 
    
评论