We described how to interrupt an AXIos request using Axios cancelToken in conjunction with axios middleware in our article handling Repeated Requests. But this approach only works for Axios Promises, and today we’ll look at a more general way to interrupt a Promise request.

In daily development, promises will inevitably be used. But we all know that promises have the disadvantage of being uncancelable once created, so today we’re going to talk about how to break promises that are being implemented.

We’re talking about interrupts, not terminations, and promises are inherently unterminable.

Promise.race()

Here’s what MDN says about the promise.race method:

The promise.race (iterable) method returns a Promise that is resolved or rejected once a Promise in the iterator is resolved or rejected.

That is, with promise.race, we can achieve the goal of ignoring the results of other promises in the array when any one of the incoming promises reaches a resolution or rejection.

Encapsulation cancellablePromiseFactory

We can use the promise.race feature to implement a Promise instance that returns an ABORT method used to interrupt the Promise request.

interface CancellablePromiseFactory<T = unknown> extends Promise<T> { abort? :(reasonToAbort: any) = > void;
}

function cancellablePromiseFactory(executor) {
  // The method used to interrupt the Promise
  let abort;
  // Construct a primitive Promise instance
  const originPromise = new Promise(executor);
  // Construct an instance of Promise specifically used to interrupt
  const promiseToAbort = new Promise(
    // Assign the reject option to ABORT
    (_, reject) = > (abort = reasonToAbort= > reject(reasonToAbort)),
  );

  // Construct a Promise Array using originPromise and promiseToAbort, and cancellablePromise using promise.race
  const cancellablePromise: CancellablePromiseFactory = Promise.race([
    originPromise,
    promiseToAbort,
  ]);

  // Mount abort to cancellablePromise
  cancellablePromise.abort = abort;

  return cancellablePromise;
}
Copy the code

Let’s test it out:

We can see that cancellablePromiseFactory constructed cancellablePromise after calling abort method was interrupted.

Note, however, that this only interrupts the invocation chain of the Promise, but as we said earlier, once a Promise is created, it cannot be cancelled, and the request is still reachable.

But we can use cancellablePromiseFactory doing many things, such as setting the request timeout: