Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

174
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda