简体   繁体   English

当 JavaScript 中的浏览器内部存在 Promise.all() 时,如何从 Puppeteer 中的 page.evaluate() 返回数据

[英]How to return data from page.evaluate() in Puppeteer, when there is Promise.all() inside browser in JavaScript

I want to find average color of all images in the page.我想找到页面中所有图像的平均颜色。 I am using Puppeteer to launch chromium and then run javascript inside browser.我正在使用 Puppeteer 启动 chromium,然后在浏览器中运行 javascript。

Problem is that I am using Promies.all to asynchronously calculate all colors inside browser.问题是我正在使用 Promies.all 异步计算浏览器内的所有 colors 。

I want to return calculated image colors to page.evaluate.我想将计算得到的图像 colors 返回到 page.evaluate。 How can I do that?我怎样才能做到这一点? Is it possible?可能吗?

Following code does not work, because imgcolors is no defined obviously, it is returned inside Promise.all callback.以下代码不起作用,因为 imgcolors 显然没有定义,它在 Promise.all 回调中返回。

   const returned = await page.evaluate(async () => {
   const fac = new FastAverageColor();
   const imgs = Array.from(document.querySelectorAll('img'));
   const imgpromises = imgs.map(img => fac.getColorAsync(img.src));


   Promise.all(imgpromises).then(imgcolors => { return imgcolors;});

   return {
     document:{
       height: document.body.scrollHeight, 
       width:document.body.scrollWidth 
     },
     imgcolors:imgcolors
   };
 });

I have tried following:我试过以下:

Promise.all(imgpromises).then(imgcolors => { 
      
      return {
        elements:elements, 
        document:{
          height: document.body.scrollHeight, 
          width:document.body.scrollWidth 
        },
        imgcolors:imgcolors
      };
    });

Now I am not returing data to page.evaluate puppeteer function.现在我不会将数据返回到 page.evaluate puppeteer function。 So const returned is undefined.所以返回的 const 是未定义的。

How to do that?怎么做? Thank you in advance!先感谢您!

In the page.evaluate function, you can return a promise, which will resolve to a value.page.evaluate function 中,可以返回一个 promise,它将解析为一个值。 In this case Promise.all returns a promise, which you can chain to return the value you want.在这种情况下, Promise.all返回一个 promise,您可以链接它以返回您想要的值。 It'd look something like this:它看起来像这样:

const returned = await page.evaluate(() => {
  const fac = new FastAverageColor();
  const imgs = Array.from(document.querySelectorAll('img'));
  const imgpromises = imgs.map(img => fac.getColorAsync(img.src));
  return Promise.all(imgpromises).then(imgcolors => { 
    return {
      document:{
        height: document.body.scrollHeight, 
        width: document.body.scrollWidth 
      },
      imgcolors: imgcolors
    };
  });
});

Alternatively, since you are using async functions, you can just use the await operator to wait for values to be resolved:或者,由于您使用的是async函数,您可以只使用await运算符来等待解析值:

const returned = await page.evaluate(async () => {
  const fac = new FastAverageColor();
  const imgs = Array.from(document.querySelectorAll('img'));
  const imgpromises = imgs.map(img => fac.getColorAsync(img.src));
  const imgcolors = await Promise.all(imgpromises);
  return {
    document:{
      height: document.body.scrollHeight, 
      width: document.body.scrollWidth 
    },
    imgcolors: imgcolors
  };
});

Note that page.evaluate can only return serializable values , ie things that can be JSON.stringify 'd.注意page.evaluate只能返回可序列化的值,即可以是JSON.stringify的东西。 It looks like imgcolors should be serializable, but in other cases, you might need to convert the values to something serializable.看起来imgcolors应该是可序列化的,但在其他情况下,您可能需要将值转换为可序列化的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM