How would you cancel a promise on which you are waiting?

28 May 23

Angular

JavaScript promises are not cancelable as of the JavaScript specification up until ES2021. Once you've created a promise, it will go through its lifecycle (pending, fulfilled, rejected) regardless of whether you need its result or not.

This can be inconvenient in cases where the operation that a promise wraps is costly, or if you are no longer interested in its result, and would like to prevent unnecessary computation.

Unfortunately, there's no built-in mechanism for stopping a promise. However, you can achieve a similar effect by wrapping your promise in another promise that supports cancellation, using an external variable to track whether the cancellation has been requested.

Here is a simple example of how you can achieve this:

let hasBeenCancelled = false; const cancellablePromise = new Promise((resolve, reject) => { originalPromise.then(result => { if(!hasBeenCancelled) { resolve(result); } }).catch(error => { if(!hasBeenCancelled) { reject(error); } }); }); // To cancel hasBeenCancelled = true;

In this example, when hasBeenCancelled is set to true, the cancellablePromise will no longer call resolve or reject, effectively ignoring the result or error from the originalPromise.

Note that this does not actually stop the originalPromise from executing, it merely ignores its result. If the operation that the originalPromise wraps is costly (e.g., a long computation or a big download), it will still continue to use resources.

In other situations where you have control over the asynchronous operations (like setTimeout or setInterval), you can make use of methods like clearTimeout or clearInterval to effectively cancel the operation.

With the introduction of Observables in libraries like RxJS, you have more control over asynchronous operations and can cancel HTTP requests or any other cancellable async operations. Angular, for example, uses RxJS and its Observables extensively.

Frontend development