Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

193
Visualizações
Can't break out of async loop

I'm trying to iterate a list of objects that I have, and want to check if it has 'Add to Cart' text, then get it's productID and then break out of the loop (since I only want the first available item).

However, I've tried breaking it but it runs through all of the elements regardless, and can't seem it figure out why. Does it have to do with async await? I'm using puppeteer.

    let putterID;
    
    await putters.every(async (putter) => {
        let inStock = await putter.$eval('.product-details .tocart a', el => el.innerHTML);
        inStock = inStock.trim();

        if (inStock == "Add To Cart") {
            putterID = await putter.$eval('.product-details .price', el => el.getAttribute('data-publishproductid'));
            console.log(`Found the first available putter with ID: ${putterID}`);
            return false;
        }

    });
about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

The built-in higher order functions don't play nice with asynchronous functions. You aren't going to be able to get .every() to do what you want like that.

If you want to do a for loop, why not just do a for loop?

for (const putter of putters) {
  let inStock = await putter.$eval('.product-details .tocart a', el => el.innerHTML);
  inStock = inStock.trim();

  if (inStock == "Add To Cart") {
      putterID = await putter.$eval('.product-details .price', el => el.getAttribute('data-publishproductid'));
      console.log(`Found the first available putter with ID: ${putterID}`);
      break;
  }
           
}

The reason why .every() isn't working the way you want is because of the following: .every() takes a synchronous function, calls it, and if all of the returned values are truthy, .every() will return true, otherwise it will return false. You passed in an asyncrounous function, which, remember, an asyncrounous function is really the same as a syncrounous function that returns a promise, that's it. So, for each item in putters, the callback will be called, and the callback is always going to return a promise, which is truthy, causing .every() to return true (which you then await for no reason - true isn't a promise, so awaiting it does nothing). Note that nothing actually waited for these callbacks to finish executing. They'll finish later on, at their own time.

about 4 years ago · Juan Pablo Isaza Relatório

0

The use of the every method in Array seems to be fully explained by Scotty Jamison. Since the async function returns a return value enclosed in Promise, the return value of the function that is a parameter of the every method in your code is Promise<void|false>, which is evaluated as true.

One more thing, if you use for loop and async/await, you can only handle one task at a time. So you can't benefit from Concurrency. Therefore, you can use the counter as follows to check every end point and get the first result you want.

function getPutterID(putters) {
  return new Promise((res, rej) => {
    let count = putters.length;
    let complete = false;
    let putterID = '';

    async function checkPutter(putter) {
      let inStock = await putter.$eval('.product-details .tocart a', el => el.innerHTML);
      inStock = inStock.trim();
      count--;

      if (inStock == "Add To Cart" && !complete) {
        complete = true;

        console.log(`Found the first available putter with ID: ${putterID}`);  
        res(putter.$eval('.product-details .price', el => el.getAttribute('data-publishproductid')));          
      }
      if (!count) rej();
    }

    putters.forEach(putter => checkPutter(putter));
  });
}

const putterID = await getPutterID(putters);

I created this code assuming that the putterID will be obtained unconditionally, but it is not complete, so it needs to be modified according to the situation. For example, if there are too many putters, you may need to control the number of async functions that run simultaneously on the checkPutter.

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda