Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

175
Views
Why .then(resolveCallback, rejectCallback) behaving differently from .then(resolveCallback).catch(rejectCallback) in polyfill of Promise.race?

I was writing polyfill for Promise.race() method using the below code snippet.

const promise = new Promise((resolve, reject) => {
  resolve('promise resolved');
});

const promise2 = Promise.resolve('promise2 resolved');

function raceCopy(promises) {
  return new Promise(function (resolve, reject) {
    for (var index = 0; index < promises.length; index++) {
        Promise.resolve(promises[index])
          .then(resolve)
          .catch(reject);
    }
  });
}

raceCopy([Promise.reject('copy rejected'), promise, promise2])
  .then((response) => console.log(response))
  .catch((error) => console.error(error));

But instead of giving the error "copy rejected" in the console, it is showing "promise resolved". I do not understand How and Why it is working like this?

What I tried?

  1. I used the existing Promise.race() API, and it is giving me the correct result "copy rejected".
Promise.race([Promise.reject('copy rejected'), promise, promise2])
 .then((response) => console.log(response))
 .catch((error) => console.error(error));
  1. Second, I changed the implementation of the raceCopy(). Something like this,
function raceCopy(promises) {
  return new Promise(function (resolve, reject) {
    for (var index = 0; index < promises.length; index++) {
      Promise.resolve(promises[index]).then(resolve, reject);
    }
  });
}

And It is also giving the correct result.

What I'm not understanding? If all the implementations are the same then Why are the results not the same for all? What am I missing here?

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

I've done some tests and found interesting results. Please be aware that this is just something I found out doing tests, so it might be not 100% accurate; a deep dive into the Ecmascript documentation would be more correct for sure.

Basically, the reason that your original code doesn't work is because of the chaining of .then and .catch. It is because of how microtasks are queued in this situation. Let's show an example using the following input:

var promises = [Promise.reject('rejected'), Promise.resolve('resolved')];

if in your code you use chaining, this is the result:

Promise.resolve(promises[index])
    .then(resolve)
    .catch(reject)

/*
-----------------------
Microtask queue
-----------------------
- .then of index 0, then enqueue the catch
- .then of index 1 (which resolve the promises)
- .catch of index 0 (which gets ignored)

------------------------------------------------------------
If we reverse the chaining
*/

Promise.resolve(promises[index])
    .catch(reject)
    .then(resolve)

/*
-----------------------
Microtask queue
-----------------------
- .catch of index 0 (which reject the promises) and don't enqueue following .then
- .then of index 1 (which gets ignored)

*/

The first .catch ends up at the end of the microtask queue because it was enqueued in the first microtask, while the other .then are all enqueued in the main task at the very beginning.

This is just speculation, but I think that it works this way to allow for a single .catch to catch errors even if there are multiple .then before it.

The correct way to fix it is probably the one you already found in your last example. By only using one .then you are only queueing one microtask and it will handle it in the correct way.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!