使用Promise中,链式的调用对于控制异步执行很重要。css
在jQuery的使用中,咱们经常使用下面的代码node
$('#app').show().css("color","red");
这是由于jQuery的对象在调用上述方法的时候,会return
此对象自己, 以方便后面能够继续调用此对象的方法。segmentfault
jQuery.fn.css = function(prop, value) { ...... return this; } jQuery.fn.show = function() { ...... return this; }
Promise是支持链式调用的,可是它是不一样于上面jQuery的链式。jQeury是调用方法返回自身,可是Promise是调用方法后返回一个新的Promise。promise
const promise = new Promise((resolve, reject) => { resolve('ok'); }) const promise$1 = promise.then(() => {console.log()}); promise$1 === promise // false
能够看到上面的promise$1是不等于promise的,若是能够在node.js 或者在浏览器中进行断点调试的话,还能看到promise$1的初始化状态是pending的。
浏览器
当Promise的实例使用then, catch, finally添加完回调方法
之后,会返回一个初始化状态为pending
的Promise的实例对象。此对象的状态咱们在外部的程序是没法进行改变的,它的状态取决于前面所注册的回调方法
的执行状况。 当回调方法
运行正常,没有产生错误或者异常,返回的值除Promise实例与自己(返回自己将会报错),返回的Promise的实例对象状态会变成resolved, 若是有错误或者异常,则会把状态变为rejected。固然了返回值是Promise的实例对象,那么次Promise实例对象的状态取决于返回的Promise实例对象的状态。 app
下图以then为例展现promise链式调用运行的流程异步
const promise$0 = Promise.resolve('resolve_0'); const promise$1 = new Promise((resolve, reject) => {resolve('resolve_1')}) promise$0.then((val) => { console.log(val) }).then(() => { console.log('continue') }); promise$1.then((val) => { console.log(val) }); //输出结果: resolve_0 resolve_1 continue
promise$0与promise$1在使用then添加回掉函数以前,状态已经从pending变为resolved,它们添加的回掉函数会被当即添加到Promise的运行队列,promise$0.then((val) => { console.log(val) })
返回的Promise实例须要等待所注册的回调函数成功执行完毕之后,此Promise的状态才从pending变为resolved。 Promise的运行机制请参考: Promise的运行机制函数
const promise = Promise.resolve('ok'); promise.then().then((val) => {console.log(val)}); // ok
因为promise经过then没有成功添加回调函数,发生了值穿透。this
const promise = Promise.resolve('complete'); promise.then((val) => { return new Promise ((resolve) => { resolve(val) console.log(val, 1); }) }) .then((val) => {console.log(val, 2)}) // complete 1 complete 2
咱们把Promise暂命名(Pa), 经过promise.then返回的Promise(暂命名Pb), Pb
状态须要根据Pa
then所注册回调方法的运行,其回调方法返回一个新的Promise(暂命名Pc),因为返回的是Promise。Pb
的状态变成取决于Pc
的状态, 当Pc
的状态变化为resolved之后,Pb
的状态也变化为resolved。spa
var promise = Promise.resolve('ok'); promise.then(() => { throw new Error('error'); }).then(() => { console.log('continue'); }).then(() => { console.log('again'); }).catch(() => { }).then(() => { console.log('completed') }) // completed
在then所注册的回调方法,发生异常之后,后续的Promise调用链的状态都是rejected,致使后续的then(resolve)
不会被推入Promise的运行队列,也就不会被运行,直到这个错误被then(,reject)
或者catch
捕获。 而使用(then(,reject))
或者catch
注册回调方法又会返回一个新的Promise,此Promise的状态又只与它们所注册的回调方法的执行相关。不会受到前面的影响。