首页 > 解决方案 > 当 JavaScript 中的浏览器中有 Promise.all() 时,如何从 Puppeteer 中的 page.evaluate() 返回数据

问题描述

我想找到页面中所有图像的平均颜色。我正在使用 Puppeteer 启动 chromium,然后在浏览器中运行 javascript。

问题是我正在使用 Promies.all 异步计算浏览器内的所有颜色。

我想将计算出的图像颜色返回给 page.evaluate。我怎样才能做到这一点?是否可以?

以下代码不起作用,因为 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
   };
 });

我试过以下:

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

现在我不会将数据返回到 page.evaluate puppeteer 函数。所以返回的 const 是未定义的。

怎么做?先感谢您!

标签: javascriptnode.jsasynchronouspromisepuppeteer

解决方案


page.evaluate函数中,您可以返回一个 Promise,它将解析为一个值。在这种情况下Promise.all,返回一个承诺,您可以将其链接以返回您想要的值。它看起来像这样:

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
    };
  });
});

或者,由于您使用的是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
  };
});

注意page.evaluate只能返回可序列化的值,即可以JSON.stringify'd'的东西。看起来imgcolors应该是可序列化的,但在其他情况下,您可能需要将值转换为可序列化的东西。


推荐阅读