您的关注意义重大
原创@前端司南
虽然Promise是开发过程中使用非常频繁的一个技术点,但是它的一些细节可能很多人都没有去关注过。我们都知道,.then
, .catch
, .finally
都可以链式调用,其本质上是因为返回了一个新的Promise实例,而这些Promise实例现在的状态是什么或者将来会变成什么状态,很多人心里可能都没个底。我自己也意识到了这一点,于是我通过一些代码试验,发现了一些共性。如果您对这块内容还没有把握,不妨看看。
阅读本文前,您应该对Promise有一些基本认识,比如:
-
Promise
有pending
,fulfilled
,rejected
三种状态,其决议函数resolve()
能将Promise
实例的状态由pending
转为fulfilled
,其决议函数reject()
能将Promise
实例的状态由pending
转为rejected
。 -
Promise
实例的状态一旦转变,不可再逆转。
本文会从一些测验代码入手,看看Promise
的几个原型方法在处理Promise
状态时的一些细节,最后对它们进行总结归纳,加深理解!
先考虑then的行为
==========
then
的语法形式如下:
p.then(onFulfilled[, onRejected]);
onFulfilled
可以接受一个value
参数,作为Promise
状态决议为fulfilled
的结果,onRejected
可以接受一个reason
参数,作为Promise
状态决议为rejected
的原因。
- 如果
onFulfilled
或onRejected
不返回值,那么.then
返回的Promise
实例的状态会变成fulfilled
,但是伴随fulfilled
的value
会是undefined
。
new Promise((resolve, reject) => {
resolve(1)
}).then(value => {
console.log('resolution occurred, and the value is: ', value)
}, reason => {
console.log('rejection occurred, and the reason is: ', reason)
}).then(value => {
console.log('resolution of the returned promise occurred, and the value is: ', value)
}, reason => {
console.log('rejection of the returned promise occurred, and the reason is: ', reason)
})
- 如果
onFulfilled
或onRejected
返回一个值x
,那么.then
返回的Promise
实例的状态会变成fulfilled
,并且伴随fulfilled
的value
会是x
。注意,一个非Promise
的普通值在被返回时会被Promise.resolve(x)
包装成为一个状态为fulfilled
的Promise
实例。
new Promise((resolve, reject) => {
reject(2)
}).then(value => {
console.log('resolution occurred, and the value is: ', value)
}, reason => {
console.log('rejection occurred, and the reason is: ', reason)
return ‘a new value’
}).then(value => {
console.log('resolution of the returned promise occurred, and the value is: ', value)
}, reason => {
console.log('rejection of the returned promise occurred, and the reason is: ', reason)
})
- 如果
onFulfilled
或onRejected
中抛出一个异常,那么.then
返回的Promise
实例的状态会变成rejected
,并且伴随rejected
的reason
是刚才抛出的异常的错误对象e
。
new Promise((resolve, reject) => {
resolve(1)
}).then(value => {
console.log('resolution occurred, and the value is: ', value)
throw new Error(‘some error occurred.’)
}, reason => {
console.log('rejection occurred, and the reason is: ', reason)
}).then(value => {
console.log('resolution of the returned promise occurred, and the value is: ', value)
}, reason => {
console.log('rejection of the returned promise occurred, and the reason is: ', reason)
})
- 如果
onFulfilled
或onRejected
返回一个Promise
实例p2
,那么不管p2
的状态是什么,.then
返回的新Promise
实例p1
的状态会取决于p2
。如果p2
现在或将来是fulfilled
,那么p1
的状态也随之变成fulfilled
,并且伴随fulfilled
的value
也与p2
进行resolve(value)
决议时传递的value
相同;
new Promise((resolve, reject) => {
resolve(1)
}).then(value => {
console.log('resolution occurred, and the value is: ', value)
return Promise.resolve(‘a fulfilled promise’)
}, reason => {
console.log('rejection occurred, and the reason is: ', reason)
}).then(value => {
console.log('resolution of the returned promise occurred, and the value is: ', value)
}, reason => {
console.log('rejection of the returned promise occurred, and the reason is: ', reason)
})
这个逻辑同样适用于rejected
的场景。也就是说,如果p2
的状态现在或将来是rejected
,那么p1
的状态也随之变成rejected
,而reason
也来源于p1
进行reject(reason)
决议时传递的reason
。
new Promise((resolve, reject) => {
reject(1)
}).then(value => {
console.log('resolution occurred, and the value is: ', value)
}, reason => {
console.log('rejection occurred, and the reason is: ', reason)
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(‘a promise rejected after 3 seconds.’)
}, 3000)
})
}).then(value => {
console.log('resolution of the returned promise occurred, and the value is: ', value)
}, reason => {
console.log('rejection of the returned promise occurred, and the reason is: ', reason)
})
再考虑catch的行为
===========
catch的语法形式如下:
p.catch(onRejected);
.catch
只会处理rejected
的情况,并且也会返回一个新的Promise
实例。
.catch(onRejected)
与then(undefined, onRejected)
在表现上是一致的。
事实上,catch(onRejected)从内部调用了then(undefined, onRejected)。
- 如果
.catch(onRejected)
的onRejected
回调中返回了一个状态为rejected
的Promise
实例,那么.catch
返回的Promise
实例的状态也将变成rejected
。
new Promise((resolve, reject) => {
reject(1)
}).catch(reason => {
console.log('rejection occurred, and the reason is: ', reason)
return Promise.reject(‘rejected’)
}).then(value => {
console.log('resolution of the returned promise occurred, and the value is: ', value)
}, reason => {
console.log('rejection of the returned promise occurred, and the reason is: ', reason)
})
- 如果
.catch(onRejected)
的onRejected
回调中抛出了异常,那么.catch
返回的Promise
实例的状态也将变成rejected
。
new Promise((resolve, reject) => {
reject(1)
}).catch(reason => {
console.log('rejection occurred, and the reason is: ', reason)
throw 2
}).then(value => {
console.log('resolution of the returned promise occurred, and the value is: ', value)
}, reason => {
console.log('rejection of the returned promise occurred, and the reason is: ', reason)
})
- 其他情况下,
.catch
返回的Promise
实例的状态将是fulfilled
。
最后看看finally
===========
不管一个Promise
的状态是fulfilled
还是rejected
,传递到finally
方法的回调函数onFinally
都会被执行。我们可以把一些公共行为放在onFinally
执行,比如把loading
状态置为false
。
注意,onFinally
不会接受任何参数,因为它从设计上并不关心Promise
实例的状态是什么。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)
![](https://i-blog.csdnimg.cn/blog_migrate/21dce104ae6807c9a10cf6ce2d839eb4.jpeg)
最后
一个好的心态和一个坚持的心很重要,很多冲着高薪的人想学习前端,但是能学到最后的没有几个,遇到困难就放弃了,这种人到处都是,就是因为有的东西难,所以他的回报才很大,我们评判一个前端开发者是什么水平,就是他解决问题的能力有多强。
分享一些简单的前端面试题以及学习路线给大家,狂戳这里即可免费领取
点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!**
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)
![](https://i-blog.csdnimg.cn/blog_migrate/21dce104ae6807c9a10cf6ce2d839eb4.jpeg)
最后
一个好的心态和一个坚持的心很重要,很多冲着高薪的人想学习前端,但是能学到最后的没有几个,遇到困难就放弃了,这种人到处都是,就是因为有的东西难,所以他的回报才很大,我们评判一个前端开发者是什么水平,就是他解决问题的能力有多强。
分享一些简单的前端面试题以及学习路线给大家,狂戳这里即可免费领取
[外链图片转存中…(img-TPz4BnaE-1712209036784)]