首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法突破异步循环

无法突破异步循环
EN

Stack Overflow用户
提问于 2022-03-22 22:02:29
回答 2查看 123关注 0票数 0

我正在尝试迭代我拥有的对象列表,并希望检查它是否有'Add‘文本,然后得到它是productID,然后脱离循环(因为我只想要第一个可用的项)。

然而,我尝试过打破它,但它运行在--所有元素的中--不管如何,而且似乎也找不出原因。这与异步等待有关吗?我在用木偶师。

代码语言:javascript
复制
    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;
        }

    });
EN

回答 2

Stack Overflow用户

发布于 2022-03-22 22:07:39

内置的高阶函数不适合异步函数。你不可能让.every()做你想做的事。

如果你想做一个for循环,为什么不直接做一个for循环?

代码语言:javascript
复制
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;
  }
           
}

.every()没有按您希望的方式工作的原因是:.every()接受一个同步函数,调用它,如果所有返回的值都是真的,.every()将返回true,否则它将返回false。您传递了一个异步函数,记住,异步函数实际上与返回承诺的同步函数相同,仅此而已。因此,对于putters中的每一项,回调都将被调用,回调将始终返回一个承诺,这是真实的,导致.every()返回true (然后您无缘无故地等待它-- true不是一个承诺,因此等待它什么都不做)。请注意,实际上没有什么可以等待这些回调完成执行。他们稍后会在他们自己的时间完成。

票数 3
EN

Stack Overflow用户

发布于 2022-03-22 23:06:52

every方法在数组中的使用似乎完全由Scotty解释。因为异步函数返回一个包含在Promise中的返回值,所以代码中作为every方法参数的函数的返回值是Promise<void|false>,它被计算为true。

还有一件事,如果使用for loopasync/await,一次只能处理一个任务。所以你不能从并发中获益。因此,您可以按如下方式使用计数器检查每个端点并获得所需的第一个结果。

代码语言:javascript
复制
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);

我创建了这段代码,假设putterID将无条件地获得,但它不是完整的,因此需要根据情况对它进行修改。例如,如果有太多的putters,您可能需要控制同步运行在checkPutter上的异步函数的数量。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71579461

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档