1.什么是Promise
Promise可以认为是一种用来解决异步处理的代码规范。常见的异步处理是使用回调函数,回调函数有两种模式,同步的回调和异步的回调。一般回调函数指的是异步的回调。
同步回调
1 | function add(a, b, callback) { callback(a + b) } |
输出结果为: before Result:3 after
异步回调
1 | function addAsync(a, b, callback) { |
输出结果: before after Result: 3
然而回调函数有个著名的坑就是“callback hell”,比如:
1 | doSomething1(function(value1) { |
为了等value1, value2, value3数据都准备好,必须要一层一层嵌套回调函数。如果一直嵌套下去,就形成了callback hell,不利于代码的阅读。
如果改用Promise的写法,只要写成如下方式就行。
1 | doSomething1().then(function() { |
可以注意到,Promise实际上是把回调函数从doSomething函数中提取到了后面的then方法里面,从而防止多重嵌套的问题。
2.Promise对象和状态
2.1 resolve & reject
Promise构造函数用来构造一个Promise对象,其中入参匿名函数中resolve和reject这两个也都是函数。如果resolve执行了,则触发promise.then中成功的回调函数;如果reject执行了,则触发promise.then中拒绝的回调函数。
1 | var promise = new Promise(function(resolve, reject) { |
2.2 Fulfilled & Rejected
Promise对象一开始的值是Pending准备状态。
执行了resolve()后,该Promise对象的状态值变为onFulfilled状态。
执行了reject()后,该Promise对象的状态值变为onRejected状态。
Promise对象的状态值一旦确定(onFulfilled或onRejected),就不会再改变。即不会从onFulfilled转为onRejected,或者从onRejected转为onFulfilled。
2.3 快捷方法
获取一个onFulfilled状态的Promise对象:
1 | Promise.resolve(1); |
获取一个onRejected状态的Promise对象:
1 | Promise.reject(new Error("BOOM")) |
3.异常捕获:then和catch
Promise的异常捕获有两种方式:
then匿名函数中的reject方法
catch方法
3.1 then中的reject方法捕获异常
这种方法只能捕获前一个Promise对象中的异常,即调用then函数的Promise对象中出现的异常。
1 | var promise = Promise.resolve(); |
但该种方法无法捕捉当前Promise对象的异常,如:
1 | var promise = Promise.resolve(); |
3.2 catch捕获异常
上述栗子若改写成如下形式,最后追加一个catch函数,则可以正常捕捉到异常。
1 | var promise = Promise.resolve(); |
catch方法可以捕获到then中抛出的错误,也能捕获前面Promise抛出的错误。 因此建议都通过catch方法捕捉异常。
1 | var promise = Promise.reject("BOOM!"); |
值得注意的是:catch方法其实等价于then(null, reject),上面可以写成:
1 | promise.then(function() { |
总结来说就是:
- 使用promise.then(onFulfilled, onRejected)的话,在 onFulfilled中发生异常的话,在onRejected中是捕获不到这个异常的。
- 在promise.then(onFulfilled).catch(onRejected)的情况下then中产生的异常能在.catch中捕获
- .then和 .catch在本质上是没有区别的需要分场合使用。