我们先打印Promise原型下都带有哪些方法
console.log(Promise.prototype)
p.then(onFulfilled,onRejected)
p.then(function(value) {
// fulfillment
}, function(reason) {
// rejection
});
onFulfilled
当Promise变成接受状态(fulfillment)时,该参数作为回调函数被调用(参考: Function)。该函数有一个参数,即接受的最终结果(the fulfillment value)。如果传入的 onFulfilled 参数类型不是函数,则会在内部被替换为(x) => x ,即原样返回 promise 最终结果的函数
onRejected (可选)
当Promise变成拒绝状态(rejection )时,该参数作为回调函数被调用(参考: Function)。该函数有一个参数,,即拒绝的原因(the rejection reason)。
直接上代码:
let promise = new Promise((resolve,reject) =>{
resolve("成功了!");
// reject("出错了!")
}))
promise.then(
function(value){
console.log(value)
},
function(reason){
console.log(reason)
}
)
输出:
成功了!then 方法返回一个Promise 对象,其允许方法链。 下面我们继续看例子:
// 出错了!
Promise.reject('出错了')
.then(res => console.log(`res1:${res}`), err => console.log(`err1:${err}`))
.then(res => console.log(`res2:${res}`), err => console.log(`err2:${err}`));
输出:
// err1:出错啦
// res2:undefined
上面代码中的Promise.reject(‘出错了’)还可以这么写:
Promise.reject('出错了')resolve和reject当传入一个字符串作为参数时,则会返回一个新的Promise实例
等价于
new Promise(reject =>{
reject('出错了')
})
如果是resolve,新的Promise对象的状态为resolve
如果是reject,新的Promise对象的状态为reject
上面的两种写法都会返回一个新的Promise实例,并且状态为reject
Promise.reject('出错了')
.then(res => {
console.log(`res1:${res}`) // 这里不执行
}, err => {
console.log(`err1:${err}`) // err1:出错了!
})
// 最后输出 : err1:出错了!
Promise状态为reject,所以执行了then下面第二个参数的方法;
我们前面说过then()的第二个参数可不选,我们继续往下看:
Promise.reject('出错了')
.then(res => {
console.log(`res1:${res}`) // 这里不执行
})
输出:
我们发现报了个未知的错误,当我们省略了第二个参数之后那么,catch()就非常有意义了,讲catch之前我们再看下then()的返回值
then方法返回一个Promise,而它的行为与then中的回调函数的返回值有关:
直接上代码:
const promise = new Promise(reject =>{
reject("出错了!")
})
// 第一个 then()
.then(res =>{
console.log(`res1:${res}`) // 这里不执行
return 1
},err =>{
console.log(`err1:${err}`) // err1:出错了!
})
// 第二个 then()
.then(res =>{
console.log(`res2:${res}`) // 1
throw "这是一个错误提示!"
},err =>{
console.log(`err2:${err}`) // 这里不执行
})
// 第三个 then()
.then(res =>{
console.log(`res3:${res}`) // 这里不执行
},err =>{
console.log(`err3:${err}`) // 这是一个错误提示!
})
// 第四个 then()
.then(res =>{
console.log(`res4:${res}`) // undefined
},err =>{
console.log(`err4:${err}`) // 这里不执行
})
// 第五个 then()
.then(res =>{
console.log(`res5:${res}`) // undefined
},err =>{
console.log(`err5:${err}`) // 这里不执行
})
如果then中的回调函数返回一个值,那么then返回的Promise将会成为接受状态,并且将返回的值作为接受状态的回调函数的参数值。我们看完返回值的介绍之后,再来分析下promise:
如果then中的回调函数抛出一个错误,那么then返回的Promise将会成为拒绝状态,并且将抛出的错误作为拒绝状态的回调函数的参数值。
如果then中的回调函数返回一个已经是接受状态的Promise,那么then返回的Promise也会成为接受状态,并且将那个Promise的接受状态的回调函数的参数值作为该被返回的Promise的接受状态回调函数的参数值。
如果then中的回调函数返回一个已经是拒绝状态的Promise,那么then返回的Promise也会成为拒绝状态,并且将那个Promise的拒绝状态的回调函数的参数值作为该被返回的Promise的拒绝状态回调函数的参数值。
如果then中的回调函数返回一个未定状态(pending)的Promise,那么then返回Promise的状态也是未定的,并且它的终态与那个Promise的终态相同;同时,它变为终态时调用的回调函数参数与那个Promise变为终态时的回调函数的参数是相同的。
promise直接执行的reject(‘出错啦’),返回的是一个promise对象,状态为reject ,所以第一个then执行的第二个参数方法,输出: res:出错了,然后return 1
我们看第二个then的输出,可以发现,第一个then的return值会作为下第二个then的回调函数的参数值,第二个then又执行了throw
第二个then的throw,使得第三个then下的Promise对象状态为reject,
所以第三个then输出: err3:这是一个错误提示! ,第三个then没有返回值,也没有执行throw ,
所以第四个then输出: res4:undefined
第四个then和第三个then一样,没有返回值,所以第五个then输出的结果和第四个一样输出: res4:undefined
我们做一下总结:
如果前一个Promise对象是resolve状态,则后一个Promise对象执行第一个参数方法(resolve)
如果前一个Promise对象是reject状态,则后一个Promise对象执行第二个参数方法(reject)
如果前一个Promise对象抛出一个自定义的异常(throw),则后一个Promise对象执行第二个参数方法(reject)
如果前一个Promise对象返回具体的值,则此数值将作为后一个Promise对象的输入,执行第一个参数方法(resolve)
如果前一个Promise对象没有返回状态(resolve或者reject),也没有抛错(throw),也没有返回具体数值,我们则认为它返回 了一个undefined,则undefined将作为后一个Promise对象的输入,执行第一个参数方法(resolve)
我们再回头看下我们前面的一个例子:
Promise.reject('出错啦')
.then(res => console.log(`res1:${res}`), err => console.log(`err1:${err}`))
.then(res => console.log(`res2:${res}`), err => console.log(`err2:${err}`));
现在看来就好理解了 因为前面是reject状态,所以第一个then执行第二个参数方法 “err => console.log(err1:${err})”
因为第一个then方法,没有返回状态,没有抛错,没有返会具体值,所以返回的是undefined,第二个then执行 “res => console.log(res2:${res}”
其实then方法懂了,catch自然也就明白了,因为,catch()就类似于.then(null, rejection)或.then(undefined, rejection)
catch用于捕获错误,它的参数也就是then的第二个参数
我们将上面的代码做一下改动
const promise = new Promise((resolve, reject) => {
reject('出错了');
})
.catch(err => {
console.log(`catch1:${err}`) // catch1:出错了
return 1;
})
.then(res => {
console.log(`then1:${res}`) // then1:1
throw "这是一个错误提示!"
})
.catch(err => {
console.log(`catch2:${err}`) // catch2:这是一个错误提示
})
.then(res => {
console.log(`then2:${res}`) // then2:undefined
})
如果上面的关于then的介绍看懂了,这个自然就会明白
关于promise的then和catch就介绍这么多,明天我们讲一下es6对promise的扩展
友情链接:点击查看所有文章目录
友情链接:点击查看 JavaScript异步系列文章目录