首页
学习
活动
专区
圈层
工具
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Scraper不会返回所有图像。认为这是因为它不是异步的。如何让for循环在一个范围内异步工作?

在JavaScript中,如果你想要在for循环中执行异步操作,你可以使用async/await结合for...of循环,或者使用Promise.all结合map函数。以下是两种常见的方法:

方法1: 使用async/awaitfor...of

代码语言:txt
复制
async function scrapeImages(urls) {
  const images = [];

  for (const url of urls) {
    try {
      const response = await fetch(url);
      const data = await response.json();
      images.push(data.image);
    } catch (error) {
      console.error(`Error fetching ${url}:`, error);
    }
  }

  return images;
}

// 使用示例
scrapeImages(['url1', 'url2', 'url3']).then(images => {
  console.log(images);
});

在这个例子中,scrapeImages函数是一个异步函数,它遍历urls数组,并且等待每个fetch请求完成后再继续下一个循环。这样可以确保所有的图像都被异步地获取。

方法2: 使用Promise.allmap

代码语言:txt
复制
async function scrapeImages(urls) {
  try {
    const promises = urls.map(async url => {
      const response = await fetch(url);
      const data = await response.json();
      return data.image;
    });

    const images = await Promise.all(promises);
    return images;
  } catch (error) {
    console.error('Error scraping images:', error);
  }
}

// 使用示例
scrapeImages(['url1', 'url2', 'url3']).then(images => {
  console.log(images);
});

在这个例子中,map函数用于创建一个Promise数组,每个Promise都是一个异步操作。Promise.all函数会等待所有的Promise都解决后返回一个包含所有结果的数组。

注意事项

  • 使用Promise.all时,如果任何一个Promise被拒绝,整个Promise.all也会立即被拒绝。因此,你可能需要处理每个请求的错误,而不是让一个错误影响所有的请求。
  • 如果你的异步操作非常多,使用Promise.all可能会导致内存不足或浏览器无响应。在这种情况下,使用async/awaitfor...of循环可能更安全。

选择哪种方法取决于你的具体需求和场景。如果你需要并行处理所有的请求并且可以接受任何一个请求失败就放弃所有请求,那么Promise.all可能更合适。如果你需要顺序处理请求或者需要更精细的错误处理,那么async/awaitfor...of循环可能更好。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

【源码解读】如何充分发挥 Scrapy 的异步能力

作为一个易上手的高性能爬虫框架,Scrapy 使用 Twisted 异步网络框架处理并发请求。 但是,在日常工作和面试过程中,经常发现有些同学会笃定地认为 Scrapy 采用的是多线程并发模型。...它一般可用于:处理即将发到网络上的请求;修改传递即将给 Spider 的响应数据;丢掉响应数据,然后生成一个新的请求;根据请求凭空构造一个响 应(并不发出实际的请求);丢弃某些请求等等。...抛出的包括 IgnoreRequest 在内的所有异常。...那么在 Scrapy 提供的可扩展组件中能否利用 Request 发起异步的网络请求呢?...该请求不会被 Spider Middleware 和 Scraper 处理,也就是说请求的回调函数不会被调用。

3.6K30

流畅的 Python 第二版(GPT 重译)(十一)

一个顺序下载脚本 示例 20-2 包含flags.py的实现,这是我们在示例 20-1 中运行的第一个脚本。它并不是很有趣,但我们将重用大部分代码和设置来实现并发脚本,因此它值得一提。...它返回一个提供__anext__的异步生成器对象,这是一个用于检索下一个项目的协程方法。...例如,我们在示例 21-1 中看到的loop.getaddrinfo(…)协程是通过调用socket模块中的getaddrinfo函数来实现的——这是一个可能需要几秒钟才能返回的阻塞函数,因为它依赖于...我认为在书中第一个异步生成器示例中使用该快捷方式可能会让人困惑,所以我将其拆分为两行。...异步工作原理及其不足之处 本章结束部分讨论了关于异步编程的高层思想,无论您使用的是哪种语言或库。 让我们首先解释为什么异步编程如此吸引人的第一个原因,接着是一个流行的神话,以及如何处理它。

22710
  • JavaScript是如何工作的:事件循环和异步编程的崛起+ 5种使用 asyncawait 更好地编码方式!

    大多数刚接触JavaScript的开发人员似乎都有这样的问题,就是认为所有函数都是同步完成,没有考虑的异步的情况。如下例子: ?...所有环境中的共同点是一个称为事件循环的内置机制,它处理程序的多个块在一段时间内通过调用调用JS引擎的执行。 这意味着JS引擎只是任意JS代码的按需执行环境,是宿主环境处理事件运行及结果。...值得注意的是,ES6指定了事件循环应该如何工作,这意味着在技术上它属于JS引擎的职责范围,不再仅仅扮演宿主环境的角色。...setTimeout(…) 是怎么工作的 需要注意的是,setTimeout(…)不会自动将回调放到事件循环队列中。它设置了一个计时器。...例如,如果在一个程序中设置了一个断点,然后阻塞并使用调试快捷方式(如“停止”),调试器将不会移动到下面,因为它只“逐步”执行同步代码。

    3.1K20

    我实在不懂Python的Asyncio

    __aiter__和__anext__,用来实现异步的迭代器(异步循环,和异步解析式).另外这个协议更改过。在3.5中,它返回awaitable。在3.6中,它返回异步生成器。...表面看起来,每个线程都有一个事件循环,但是实际上它不是这么工作的。 下面是我猜想它如何工作的: 如果你在主线程,那么事件循环会在你调用asyncio.get_event_loop()的时候被创建。...asyncio.get_event_loop()返回与线程绑定的事件循环,并不是返回当前运行的那个事件循环。 这些行为组合起来,非常地让人困扰。...这意味着,你在一个协程中调用asyncio.get_evenet_loop(),你并不知道返回的事件循环是哪个。这也是为什么所有的API都会需要一个可选的loop参数的原因。...这是因为,在生成器函数中的return,实际上是抛出了一个StopIteration异常,并且携带一个参数值代表返回值。这个异常不会被迭代器协议抓取,只会被协程代码获取。

    1.3K20

    node中常见的10个错误

    这是因为调用回调函数后,并不会自动结束当前执行函数。如果第一个 “return” 注释掉,然后给这个函数传进一个非字符串密码,导致 “computeHash” 仍然会被调用。...这就是 Node.js 中如何处理错误的另外一种方式。另外,有必要遵循所有回调函数的参数(err, …)模式,所有回调函数的第一个参数期待是一个错误对象。...错误 #7:认为数字是整型 数字在 JavaScript中都是浮点型,JS 没有整型。你可能不能预料到这将是一个问题,因为数大到超出浮点型范围的情况并不常见。...这不是一个多么糟糕的问题,因为 Gravatar 返回的图像并不是很大。然而,想象一下,如果我们代理的内容大小有成千上万兆。...开发者设计和实现现代应用时常常推荐的一个最佳实践是:快速失败,快速迭代。 如果发生一个意料之外的错误,不要试图去处理它,而是让你的程序崩溃,并有个监控者在几秒后重启它。

    1.9K60

    所有你需要知道的关于完全理解 Node.js 事件循环及其度量

    这个事件循环可能是平台中最被误解的概念。当我们提及事件循环监测的主题时,我们花了很多精力来正确地理解我们实际监视的内容。 在本文中,我将带大家重新认知事件循环是如何工作以及它是如何正确地监视。...误解3:事件循环类似栈或队列 误解 事件循环采用先进先出的方式执行异步任务,类似于队列,当一个任务执行完毕后调用对应的回调函数。 现实 虽然涉及到类似队列的结构,事件循环并不是采用栈的方式处理任务。...,我们让被调用的 http 服务器在 1s 后返回数据。...因此,我们正在收集信息以将这些数据纳入我们的异常检测。 回到事件循环 当然,在不了解如何从可能的行动中解决问题的情况下,衡量标准本身就不会有太大的帮助。当事件循环快耗尽时,这里有几个提示。 ?...事件循环耗尽 利用所有 CPU Node.js 应用程序在单个线程上运行。在多核机器上,这意味着负载不会分布在所有内核上。

    1.3K110

    node中常见的10个错误

    这是因为调用回调函数后,并不会自动结束当前执行函数。如果第一个 “return” 注释掉,然后给这个函数传进一个非字符串密码,导致 “computeHash” 仍然会被调用。...这就是 Node.js 中如何处理错误的另外一种方式。另外,有必要遵循所有回调函数的参数(err, …)模式,所有回调函数的第一个参数期待是一个错误对象。...错误 #7:认为数字是整型 数字在 JavaScript中都是浮点型,JS 没有整型。你可能不能预料到这将是一个问题,因为数大到超出浮点型范围的情况并不常见。...这不是一个多么糟糕的问题,因为 Gravatar 返回的图像并不是很大。然而,想象一下,如果我们代理的内容大小有成千上万兆。...开发者设计和实现现代应用时常常推荐的一个最佳实践是:快速失败,快速迭代。 如果发生一个意料之外的错误,不要试图去处理它,而是让你的程序崩溃,并有个监控者在几秒后重启它。

    1.4K30

    Node.js创造者,Ryan Dahl专访

    Ryan: 研究生院的经历,让我擅长处理非常抽象的问题,但网站开发工作是一个非常具体的过程,但我真的想把它变成一个美丽的数学理论,就像我在研究生院经历的那样。...但碰巧的是,我相对失业,有一些空闲时间,可以连续工作几个月,这就是我可以创造它的一些必要条件吧。 Pramod: 你做得很好。Node是建立在“纯粹的异步”编程模型的思想,这个想法是如何产生的?...我认为它实际上是非阻塞I/O,但是他们向用户提供的接口是阻塞的,我认为这是一个更好的编程模型,如果它阻塞的话,你可以在很多action下仔细想想你在做什么。...因为没有多进程,如果你正在做阻塞I/O,你实际上不能处理请求,你一次只做一件,那是永远不会成功的。而我喜欢让HTTP服务器工作得很好。...所以,我有一个demo,一个HTTP服务器,然后是一个原始TCP服务器,我让这些东西工作得很好,让人们可以坐下来,建立一个网站,而不会经历太多的麻烦。

    1.4K41

    动图学JS异步: Promises & AsyncAwait

    好了,那么现在我们知道如何更好的控制Promise对象了,但是它实际上有什么作用呢? 在之前我们讲述了一个关于对图像处理的代码示例,最终得到的是一个回调地狱般的xx代码。...在JavaScript事件循环[2]中,我们不是也可以使用原生浏览器的方法,如setTimeout来实现某种异步行为? 是的!...事件循环对于这些任务给出了不同的优先级。 1.所有函数都是在当前调用栈执行,当它们返回一个值时候,就会从调用栈弹出。...虽然我们的计时器提供的时间间隔值是0,但是这个回调仍然马上被推到Web API的第一位,之后它被添加到macrotasks queue,这是因为setTimeout是一个macro task! ?...最终, 所有的执行结束! ? Async/Await ES7在JavaScript中引入了一个新的方法来添加异步行为,并且它让promise使用起来更加容易了!

    1.1K20

    深入理解GCD

    一个异步函数,刚好相反,会立即返回,预定的任务会完成但不会等它完成。因此,一个异步函数不会阻塞当前线程去执行下一个函数。...因为这是一个 dispatch_async() ,Block 会被异步地提交,意味着调用线程地执行将会继续。这就使得 viewDidLoad 更早地在主线程完成,让加载过程感觉起来更加快速。...准备下一步 在本教程中,你学习了如何让你的代码线程安全,以及在执行 CPU 密集型任务时如何保持主线程的响应性。 你可以下载 GooglyPuff 项目,它包含了目前所有本教程中编写的实现。...如果在所有任务完成前超时了,该函数会返回一个非零值。你可以对此返回值做条件判断以确定是否超出等待周期;然而,你在这里用 DISPATCH_TIME_FOREVER 让它永远等待。...这个函数是同步的,所以和普通的 for 循环一样,它只会在所有工作都完成后才会返回。

    1.5K10

    Swift 中的 asyncawait

    这是一个非常简化的描述,但它应该让你知道 Swift 中的并发性对你的应用程序的性能是多么重要。有了新的 async 方法和 await 语句,我们可以定义方法来进行异步工作。...执行数据请求 } fetchImages 方法被定义为异步且可以抛出异常,这意味着它正在执行一个可失败的异步作业。如果一切顺利,该方法将返回一组图像,如果出现问题,则抛出错误。...你可以把它们(async-await)看作是Swift中最好的朋友,因为一个永远不会离开另一个,你基本上可以这样说: "Await 正在等待来自他的伙伴async 的回调" 尽管这听起来很幼稚,但这并不是骗人的...调用方法结束 正如你所看到的,调用方法在获取图像之前结束。最终,我们收到了一个结果,然后我们回到了完成回调的流程中。这是一个非结构化的执行顺序,可能很难遵循。...最终我们会发现,我们真的不再需要它们了,因为我们可以利用try-catch语句与async-await相结合。 Result枚举不会很快消失,因为它仍然在整个Swift项目的许多地方被使用。

    3.5K30

    【JS】239-浅析JavaScript异步

    但是在 JavaScript中,你会感觉按钮按下去的时候卡了一下,然后看到一个最终结果 999999,而没有中间过程,这就是因为在 updateSync函数运行过程中 UI更新被阻塞,只有当它结束退出后才会更新...)很容易实现链式调用,而取值器(getter)相对来说不好实现链式调用,因为你需要取值器返回你需要的数据而不是this指针,如果要实现链式方法,可以用回调函数来实现。...完成 Node整个异步 IO环节的有事件循环、观察者、请求对象。 事件循环机制 单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。...也就是说,它指定的任务总是发生在所有异步任务之前,当前主线程的末尾。...一个异步过程的整个过程:主线程发一起一个异步请求,相应的工作线程接收请求并告知主线程已收到通知(异步函数返回);主线程可以继续执行后面的代码,同时工作线程执行异步任务;工作线程完成工作后,通知主线程;主线程收到通知后

    84220

    【JS】368- 浅析JavaScript异步

    但是在 JavaScript中,你会感觉按钮按下去的时候卡了一下,然后看到一个最终结果 999999,而没有中间过程,这就是因为在 updateSync函数运行过程中 UI更新被阻塞,只有当它结束退出后才会更新...)很容易实现链式调用,而取值器(getter)相对来说不好实现链式调用,因为你需要取值器返回你需要的数据而不是this指针,如果要实现链式方法,可以用回调函数来实现。...完成 Node整个异步 IO环节的有事件循环、观察者、请求对象。 事件循环机制 单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。...也就是说,它指定的任务总是发生在所有异步任务之前,当前主线程的末尾。...一个异步过程的整个过程:主线程发一起一个异步请求,相应的工作线程接收请求并告知主线程已收到通知(异步函数返回);主线程可以继续执行后面的代码,同时工作线程执行异步任务;工作线程完成工作后,通知主线程;主线程收到通知后

    76530

    Swift 中的 asyncawait ——代码实例详解

    这是一个非常简化的描述,但它应该让你知道 Swift 中的并发性对你的应用程序的性能是多么重要。有了新的 async 方法和 await 语句,我们可以定义方法来进行异步工作。...执行数据请求 } fetchImages 方法被定义为异步且可以抛出异常,这意味着它正在执行一个可失败的异步作业。如果一切顺利,该方法将返回一组图像,如果出现问题,则抛出错误。...调用方法结束 正如你所看到的,调用方法在获取图像之前结束。最终,我们收到了一个结果,然后我们回到了完成回调的流程中。这是一个非结构化的执行顺序,可能很难遵循。...不过,我强烈建议逐步应用改变,因为它允许你隔离改变的部分,使你更容易测试你的改变是否如预期那样工作。...Result 枚举不会很快消失,因为它仍然在整个 Swift 项目的许多地方被使用。然而,一旦 async-await 的采用率越来越高,我就不会惊讶地看到它被废弃。

    2.9K10

    JavaScript是如何工作的:Web Workers的构建块+ 5个使用他们的场景

    JavaScript是如何工作的:事件循环和异步编程的崛起+ 5种使用 async/await 更好地编码方式!...不是一个HTTP请求而是一个阻塞代码(比如一个内容很多的for loop循环),就没有办法及时清空事件循环,浏览器的 UI 渲染就会被阻塞,页面无法及时响应给用户。...所有这些计算逻辑都可以添加到 Web Worker 中,以避免阻塞 UI线程。更好的是——可以很容易地在多个 workers 之间(以及在多个cpu之间)分割图像呈现。...这是一个使用 Web Worker 非常好的场景,因为它不需要访问 DOM 或任何花哨的东西——它是完成其工作的纯算法。...只要是在 Web Worker 中工作的,对于端用户就是无缝的,不会影响到体验。

    84010

    如何不编程用 ChatGPT 爬取网站数据?

    我觉得敢于设想,是很必要的。这是个好问题。 我之前在知识星球里就为你写过一篇相关的文章,叫做《如何用 ChatGPT 的 Advanced Data Analysis 帮你采集数据》。...页面上还列出了一些默认问题,可以帮助你了解它的工作方式。我选择了第一个问题:「我如何从网站获取数据?」 根据回答,我们可以利用 Scraper GPT 获取三类不同的数据:文本、链接和图像。...最后 Scraper GPT 还表示,如果需要更进一步的信息,随时可以告诉它。真是服务态度一流。 怎么样?是不是不用编程,直接搞定文本获取? 图像 接下来咱们来试试获取网页中的全部图像。...Scraper GPT 把翟老师的职称、联系方式、研究领域等内容都抓取到了。 更进一步还抓取了翟老师的教育背景、工作经历、研究生指导等。 在翟老师的个人主页上,这些信息位于默认页面底部。...我的能力集中在处理页面由服务器提供的静态内容中的文本、链接或图像,而不是在客户端脚本运行之前。 如果有 JavaScript 生成的内容或信息是动态加载的,我可能无法直接通过简单的抓取访问到它。

    28210

    Scrapy源码解读

    回调函数描述事件完成后如何处理事件。Event loop事件循环轮询poll,并在事件发生时将他们分发给回调函数。这样的方式,就允许程序在不使用多线程的情况下持续执行(协程的概念)。...这样做可以使这个函数变成一个“生成器函数”,它返回一个”iterator“可以用来以一系列步骤运行这个函数. 每个迭代循环都会重启这个函数,继续执行到下一个 yield 语句。...这与异步系统中的回调工作方式非常类似. 我们可以把 while 循环视作 reactor, 把生成器视作一系列由 yield 语句分隔的回调函数....这是一个异步函数,里面会对所有核心组件进行实例化,等到后面调用self.crawler_process.start(),才真正开始启动reactor事件循环,标志着所有爬虫正式运行。...综合以上的源码分析,我们大致有如下的理解: 因为爬虫整体过程有许多请求网络在等待的操作,采用基于事件驱动的twisted异步框架,实现在单线程下的多任务并发。

    81330

    同步与异步 Python 有何不同?

    任何时候,一台异步服务器都会有上百或上千个活跃的任务,它们都在循环的管理下执行自己的工作。 你可能想知道异步任务之间的并行是如何实现的。...当一个任务需要等待一个外部事件(例如,一个数据库服务器的响应)时,不会像一个同步的 worker 那样等待,而是会告诉循环,它需要等待什么,然后将控制权返回给它。...循环就能够在这个任务被数据库阻塞的时候发现另外一个准备就绪的任务。最终,数据库将发送一个响应,而那时循环会认为第一个的任务已经准备好再次运行,并将尽快恢复它。...这非常酷,因为在某些情况下,这让同步代码可以被异步执行,这是诸如asyncio之类的基于协程的方案做不到的。 那么在 greenlet 方面,跟asyncio对等的库有哪些?...如果你查看单个请求的处理时间,你不会看到有很大差别,甚至异步可能更慢,因为异步有更多并发的任务在争夺 CPU。 4 结论 希望本文能解答异步代码的一些困惑和误解。

    1.2K20

    关于NodeJS工作原理的五个误解

    EventEmitter 实例跟踪与 EventEmitter 实例本身内的事件相关联的所有事件和其实例本身。它不会在事件循环队列中调度任何事件。...一旦预定的异步任务完成,将调用提供的任何回调,并且该回调函数将再次占据该堆栈。此时,启动异步任务的函数将不再可用,因为它已经返回。 考虑到以上定义,请尝试确定以下函数是异步还是同步。...尽管这句话在一定程度上是正确的,但并不是100%正确,因为有些 CPU 密集型函数不会阻塞事件循环。 一般来说,加密操作和压缩操作是受 CPU 高度限制的。...由于这个原因,某些加密函数和 zlib 函数的异步版本以在 libuv 线程池上执行计算的方式编写,这样它们就不会阻塞事件循环。...因此,执行阻塞CPU密集型操作的一个工作线程不会影响其他工作线程的事件循环,从而使它们可用于任何传入的工作。 但是,在撰写本文时,IDE对 Worker Threads 的支持还不是最大。

    1.6K20

    《Learning Scrapy》(中文版)第10章 理解Scrapy的性能

    爬虫和pipelines的代码是异步的,会包含必要的延迟,但二者不会是瓶颈。爬虫和pipelines很少会做繁重的处理工作。如果是的话,服务器的CPU则是瓶颈。...它的代码有些复杂,你可以在speed/spiders/speed.py找到,但我们不会深入讲解它。...这里容易让人迷惑的地方是,要是API的调用比网页请求还快,我们根本不会观察到性能的下降。...这是因为scrape显示Reponses,而p/line显示Items。 第二个是图11中像一个浴缸的函数。部分原因是纵坐标轴造成的。在左侧,有非常高延迟,因为达到了内存极限。...在最后一章中,我们会学习如何进一步提高性能,不是使用一台服务器,而是在多台服务器上分布多个爬虫。---- ----

    1.3K20
    领券