0

I need the promise to resolve within the specified time or reject it. I'm doing this:

function myFunction(url, maxWait) {
    maxWait = maxWait || 5000; // milliseconds

    var promise = new Promise(function(resolve, reject) {
        $.ajax({
            url: url,
        })
        .done(function(data) {
            resolve(data);
        });
    });

    var timeout = new Promise(function(resolve, reject) {
        var id = setTimeout(function() {
            clearTimeout(id);
            reject(Error("Timed out"));
        }, maxWait);
    });

    return Promise.race([promise, timeout]);
}

... but the timeout always runs, what am I doing wrong? Basically I need to set a timeout on the promise so it resolves or rejects within maxWait ms.

eozzy
  • 66,048
  • 104
  • 272
  • 428

1 Answers1

0

You need to have the timeout ids somewhere where the opposite promise can see them. Then when the first promise resolves, you cancel the timeout of the other one.

Here's a simplified version without the ajax:

function myFunction() {
  var id1, id2 // ids in outer scope

  var timeout1 = new Promise(function(resolve, reject) {
    id1 = setTimeout(function() {
      clearTimeout(id2); // clear the *other* timeout
      resolve("Timed out2");
    }, 1000);
  });

  var timeout2 = new Promise(function(resolve, reject) {
    id2 = setTimeout(function() {
      console.log("timeout finished")
      clearTimeout(id1);
      reject(Error("Timed out"));
    }, 1500);
  });

  return Promise.race([timeout1, timeout2]);
}

myFunction().then(console.log).catch(console.log)

This will cause one of the promises to never resolve, but so long as you don't hold a reference to to, it should be garbage collected.

Mark
  • 90,562
  • 7
  • 108
  • 148