返回

他山之石之我对AbortSignal的一点认识

前端

大家好,我卡颂。遥想数年前的一次面试,面试官问我:promise有什么缺点?真是百思不得姐啊...答案是:promise一旦初始化,就不能中止。这是由promise的实现决定的。AbortSignal则是在一定程度上解决了这个问题。

AbortSignal是前端常用的一个类,主要用于解决promise不能中止的问题。当一个promise被创建时,它就会有一个对应的AbortSignal对象。这个AbortSignal对象可以用来中止promise。当AbortSignal对象被中止时,对应的promise也会被中止。

AbortSignal的用法非常简单。首先,我们需要创建一个AbortSignal对象。然后,我们将这个AbortSignal对象传递给promise的构造函数。当我们需要中止promise时,我们可以调用AbortSignal对象的abort方法。

下面是一个使用AbortSignal中止promise的示例代码:

const abortController = new AbortController();
const signal = abortController.signal;

const promise = new Promise((resolve, reject) => {
  fetch('https://example.com', { signal })
    .then(response => {
      resolve(response);
    })
    .catch(error => {
      reject(error);
    });
});

abortController.abort();

在上面的代码中,我们首先创建了一个AbortController对象。然后,我们从AbortController对象中获取一个AbortSignal对象。接下来,我们将这个AbortSignal对象传递给promise的构造函数。最后,我们调用AbortController对象的abort方法来中止promise。

AbortSignal还可以用来中止request、fetch、axios和Ajax请求。具体的使用方法与上面介绍的一致。

总之,AbortSignal是一个非常有用的类,可以帮助我们中止promise和各种请求。在实际开发中,我们可以根据需要来使用AbortSignal。

除了AbortSignal之外,还有其他一些方法可以用来中止promise。例如,我们可以使用Promise.race()方法来中止promise。Promise.race()方法接受多个promise作为参数,并返回最先完成的promise。如果我们想要中止其中一个promise,我们可以将这个promise包装在一个AbortSignal对象中。当AbortSignal对象被中止时,对应的promise也会被中止。

const abortController = new AbortController();
const signal = abortController.signal;

const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('promise1');
  }, 1000);
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('promise2');
  }, 2000);
});

const promise3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('promise3');
  }, 3000);
});

const promises = [promise1, promise2, promise3];

Promise.race(promises.map(promise => promise.then(value => ({ value, signal }))))
  .then(({ value }) => {
    console.log(value);
  })
  .catch(error => {
    console.error(error);
  });

abortController.abort();

在上面的代码中,我们首先创建了一个AbortController对象。然后,我们从AbortController对象中获取一个AbortSignal对象。接下来,我们将这个AbortSignal对象包装在每个promise中。最后,我们使用Promise.race()方法来中止promise。当AbortController对象的abort方法被调用时,对应的promise也会被中止。

希望这篇文章对大家有所帮助。如果大家有任何问题,欢迎随时提问。