Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
题解
当面试官问我们:“如何中断Promise?”的时候,我们应该怎么去回答?
- 如果前面已经问过了
Promise相关的,那这时候你可以只回答“如何中断”; - 如果前面没问过
Promise相关的,那你可以先简单介绍一下Promise以及Promise的一些常见用法,然后再说“如何中断”,注意,介绍Promise的时候不要太过啰嗦,重点还是要放到“中断”上来。
这篇文章我们的重点也是“中断Promise”,就不过多地介绍Promise以及它的用法了,不太清楚的可以看我前面的文章“Promise详解与应用”。
首先我们要搞清楚一点,Promise有一个很明显的缺点:一旦创建就无法取消。所以从本质上来说Promise一旦创建就无法终止。这一点我们在答题的时候一定要提到。
那既然无法被终止,那我们如何去中断呢?请看~
思路
- 当函数返回一个新的
Promise对象时,原Promise对象的状态将跟新对象保持一致,因此,当新对象保持Pending状态时,原Promise链将会中止执行,所以我们可以利用这一特性中断调用链。 - 把
pending状态的Promise给reject掉,这个应该是比较熟悉的吧,不就是我们平时设置的网络超时吗,利用这一点也可以实现中断Promise。 - 在
then中直接抛错,这样就不会执行后面的then,直接跳到catch方法打印error。
有了上面这几种思路之后,那我们来验证一下吧。
实现:
当新对象保持pending状态时,原Promise链会中止执行
Promise.resolve().then(() => {
console.log('1')
return new Promise(() => {})
})
.then(() => console.log('2'))
.then(() => console.log('3'))
.catch((err) => console.log(err))
结果:
设置超时时间,一旦超时就中断,我们可以用定时器模拟一个网络请求,利用Promise.race()
function fun(p,timeout) {
const wait = new Promise((resolve,reject) => {
setTimeout(() => {
reject('请求超时')
},timeout)
})
return Promise.race([p, wait])
}
fun(new Promise(() => console.log('1')), 2000)
结果:
在then中直接抛错
Promise.resolve()
.then(() => console.log('1'))
.then(() => {
console.log('2')
throw '错误'
})
.then(() => console.log('3'))
.catch((err) => console.log(err))
结果:
其实并不推荐这种做法,因为如果链路中对错误进行了捕获,后面的then函数还是会继续执行的。