Skip to content
Advertisement

JavaScript Promises – force promise to resolve

Considering that I have the following:

const timeoutPromise = new Promise(resolve => setTimeout(resolve("Failure"), 5000));

const response = await Promise.race([infinite_task, timeoutPromise]);

The infinite_task is a promise that never resolves or rejects. I tried to use Promise.race but it will never compare both promises, since infinite_task never ends.

How can I force infinite_task to resolve after a timeout (in this case, after 5 seconds)?

Advertisement

Answer

You have a behavioural error in the setTimeout function. You are passing the result of the resolve function (that is undefined) as parameter of the setTimeout, when you should pass a callback. This means that your timeoutPromise actually resolves instantly and not after the real timeout. This behaves as you expect:

let infinite_task = new Promise(() => { /* never resolving promise */ });

const timeoutPromise = new Promise(resolve => {
  setTimeout(() => { // this is the needed change to the callback
    resolve("Failure")
  }, 5000)  
});

const response = Promise.race([
    infinite_task,
    timeoutPromise
])
.then(e => console.log('Result:', e));

// making it a function
function awaitFor(promise, millis) {
  return Promise.race([
    promise,
    new Promise((resolve, reject) => {
        // NOTE: here better to use reject so we can use catch to see if 
        // the promise was fulfilled or timeout was elasped
        setTimeout(() => reject('timeout'), millis)
    })
  ]);
}

awaitFor(infinite_task, 10000)
  .then(() => console.log('infinite task was not so infinite!'))
  .catch(e => console.log('Error2:', e));

Decomposing your code:

For clarity I decompose in steps what you did:

const timeoutPromise = new Promise(resolve => setTimeout(resolve("Failure"), 5000));

// Promise function dec.
const timeoutPromise = new Promise(function(resolve) {
    setTimeout(resolve("Failure"), 5000)
});

// setTimeout arguments dec.
const timeoutPromise = new Promise(resolve => {
    let timeout = 5000;
    let callback = resolve("Failure") // this fulfill the promise and returns undefined
    setTimeout(callback, timeout);
});

// variable-values substitutions
const timeoutPromise = new Promise(resolve => {
    resolve("Failure") // this fulfill the promise and returns undefined
    setTimeout(undefined, 5000); // this pratically do nothing
});

// contraction (actual code executed, at the end of the day)
const timeoutPromise = new Promise(resolve => resolve("Failure"));
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement