1

I have created a long running Promise that I'm wrapping with this simple function that I created to create a watch a Promise race.

The function is below:

export const promiseTimeout = (
  promise,
  timeoutMs = 10000, //10 secs
  message = 'Timeout reached, please try again',
) =>
  Promise.race([
    promise,
    new Promise((resolve, reject) =>
      setTimeout(() => {
        reject(message);
      }, timeoutMs),
    ),
  ]);

The way I'm planning to use it is that I would pass the long running Promise that might require other unpredictable resources such as internet, file, system setting, etc.

Usage would be like below: const result = await promiseTimeout(longRunningFunction()) .catch(err => /* do something with the error , show toast or alert */);;

What is currently happening with this is that whenever the timeout is reached it would call the catch but the operation of the longRunningFunction will still continue.

How can I stop the operations on the passed Promise in argument if ever timeout is reached?

Jojo Narte
  • 2,767
  • 2
  • 30
  • 52

1 Answers1

1

How can I stop the operations on the passed Promise in argument if ever timeout is reached?

Hey, sorry, we don't have cancellation of async functions yet.

Note however that a promise is a value and not an action, once you have the promise given we won't have cancellable promises in JavaScript it is impossible to cancel the action.

The only thing you can do is to do something like the cancellation proposal and write your longRunningFunction with a token:

function longRunningFunction() {
   const signal = { requested: false };
   async function internal() {
     // your regular code here
     // whenever you can stop execution:
     if(signal.requested) {
       return; // and cancel internal operations
     }
   }
   let res = internal();
   res.signal = signal;
   return res;
}

Then write your race as:

export const promiseTimeout = (
  promise,
  timeoutMs = 10000, //10 secs
  message = 'Timeout reached, please try again',
) =>
  Promise.race([
    promise,
    new Promise((resolve, reject) =>
      setTimeout(() => {
        reject(message);
        if (promise.signal) promise.signal.requested = true;
      }, timeoutMs),
    ),
  ]);
Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504