Promise,该如何中断?

1,273 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

题解

当面试官问我们:“如何中断Promise?”的时候,我们应该怎么去回答?

  1. 如果前面已经问过了Promise相关的,那这时候你可以只回答“如何中断”;
  2. 如果前面没问过Promise相关的,那你可以先简单介绍一下Promise以及Promise的一些常见用法,然后再说“如何中断”,注意,介绍Promise的时候不要太过啰嗦,重点还是要放到“中断”上来。

这篇文章我们的重点也是“中断Promise”,就不过多地介绍Promise以及它的用法了,不太清楚的可以看我前面的文章“Promise详解与应用”。

首先我们要搞清楚一点,Promise有一个很明显的缺点:一旦创建就无法取消。所以从本质上来说Promise一旦创建就无法终止。这一点我们在答题的时候一定要提到。

那既然无法被终止,那我们如何去中断呢?请看~

思路

  1. 当函数返回一个新的Promise对象时,原Promise对象的状态将跟新对象保持一致,因此,当新对象保持Pending状态时,原Promise链将会中止执行,所以我们可以利用这一特性中断调用链。
  2. pending状态的Promisereject掉,这个应该是比较熟悉的吧,不就是我们平时设置的网络超时吗,利用这一点也可以实现中断Promise
  3. 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))

结果:

image.png

设置超时时间,一旦超时就中断,我们可以用定时器模拟一个网络请求,利用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)

结果:

image.png

在then中直接抛错

Promise.resolve()
.then(() => console.log('1'))
.then(() => {
    console.log('2')
    throw '错误'
})
.then(() => console.log('3'))
.catch((err) => console.log(err))

结果:

image.png

其实并不推荐这种做法,因为如果链路中对错误进行了捕获,后面的then函数还是会继续执行的。