前言
promise很多人都会用,但往往使用的时候有一些注意不到的细节问题,阮一峰大佬写的ES6入门教程其实已经很详细了,我看过很多遍,经常都会翻出来看;现在这篇博客就探讨一下文档上没有讲或者没有讲得特别清楚的地方以及容易误解的地方。
reject了也还会走到then?
then很多人在使用的时候会下意识地以为promise执行成功了resolve了之后才会走到then里面去,但很多人也都忽略了个细节,then方法接受两个参数,第一个参数是resolve之后的回调,而第二个参数则是reject之后的回调。大多数人都很少使用到第二个参数,捕获错误通常也都是使用catch,自然而然就忽略了这第二个参数。
reject了依旧会走到then的第一个回调?
上面说了,then有两个参数,第一个是resolve的回调,第二个是reject的回调;但其实即使是promise内命中的是reject的逻辑调用了reject也依然有可能走到resolve的回调里面去,看看下面这段代码
const promise1 = new Promise((resolve,reject)=>{
setTimeout(()=>{
reject('error')
},1000)
})
promise1.catch(e=>{
console.log(e)
}).then(e=>{
console.log('then',e)
})
// 执行输出
//error
//then undefined
上面这段代码1秒后执行了reject,但依旧进到了then里面,其实代码中如果把then写到catch前面去是不会走到then的;也许你觉得我永远不会这么写,我的then永远写在catch后面,但是当你想要去封装一些返回promise,而你又在封装返回的promise里面写了catch之后,你就会发现问题,你返回出去的promise当reject的时候就会走到then里面去。
重新理解then
首先,把原本then是运行成功resolve的回调这个观念去掉,then直接了当的翻译就是“然后”,then本身就是链式的,当然catch也是,所以上面代码里then写在catch的后面其实意思就是“捕获了错误,然后呢?”,结果catch里面啥数据也没给到then,所以then只能输出了个undefined,promise之后的then和catch都是按顺序执行的,如果promise跑到reject之后,**第一个catch之前的then全都不会执行,但第一个catch之后的then都会顺序执行,而之后的catch如果前面的错误被捕获了则不会执行,只有当前面的then里面有未被捕获的错误才会执行。**具体参考下面的代码
const promise1 = new Promise((resolve,reject)=>{
setTimeout(()=>{
reject('error')
},1000)
})
promise1.then(e=>{
console.log('then',e)
}).catch(e=>{
console.log(e)
return 'test'
}).then(e=>{
console.log(e)
console.log(a) //错误代码
}).catch(e=>{
console.log('err',e)
}).catch(e=>{
console.log('err2',e)
}).then(e=>{
console.log('then',1)
})
// 输出结果
// error
// test
// err ReferenceError: a is not defined
// then 1