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

142
Vistas
Asynchronous call stack execution gap

I am reading "Eloquent JavaScript" and at the end of Asynchronous chapter there is a section about execution gap in asynchronous operations and it shows an example. The example code below from the book is not runable as it uses some made up scenario.

function anyStorage(nest, source, name) {
   if (source == nest.name) return storage(nest, name); else return routeRequest(nest, source, "storage", name);
}

async function chicks(nest, year) {
   let list = "";
   await Promise.all(network(nest).map(async name => {
     list += `${name}: ${
     await anyStorage(nest, name, `chicks in ${year}`)
   }\n`; }));
   return list;
 }

It says the problem with this code, as I understand, is each asynchronous call e.g. anyStorage will actually concatenate an empty list and can't see the mutation from other asynchronous calls.

I tried to replicate this problem as below:

function delay(n) {
    return Promise.resolve(setTimeout(()=>{}, n*1000));
}

async function asyncSum(a) {
    let sum = 0;
    await Promise.all(a.map(async i => sum += await delay(i)));
    return sum;
}

asyncSum([1,2,3,4]).then(value => console.log(value));

But this works as expected. It prints the sum correctly. So did I misunderstand the book or there is something wrong with my example?

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

The problem in the original code is that here:

list += `${name}: ${ await ...

The list += is like doing list = list + - but the second list:

list = list +
       ^^^^

refers to the list at that moment - before any of the asynchronous calls have completed. Eventually one of them will complete and assigns to list. But once the next one resolves, because the list it has refers to the original one, not the newly updated one, the prior results will be lost.

Here's a demo:

const getMultipliedNum = num => Promise.resolve(num * 3);

(async() => {
  let list = "";
  await Promise.all([1, 2, 3].map(async num => {
    list += `${num}: ${ await getMultipliedNum(num)}\n`;
  }));
  console.log(list);
})();

Your example has the same issue, though the delay function is broken - the result is 4, which is only the result of the final setTimeout call (because setTimeout returns the timeout ID). Fixing it to demonstrate the problem:

function delay(n) {
    return Promise.resolve(n);
}

async function asyncSum(a) {
    let sum = 0;
    await Promise.all(a.map(async i => sum += await delay(i)));
    return sum;
}

asyncSum([1,2,3,4]).then(value => console.log(value));

The result is 4, rather than 10 - this demonstrates that sum += await somethingElse inside a parallel loop doesn't work.

Another way of looking at it:

sum += await somethingElse

is like doing

const currentValueOfSum = sum;
sum = currentValueOfSum + await somethingElse;
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