如何从异步/等待函数返回值?

时间:2018-09-26 02:51:27

标签: node.js ecmascript-6 async-await puppeteer ecmascript-2017

使用操纵up将来自2个不同网页的数据收集到数组中以供以后比较。但是,程序不会在继续进行之前等待返回的数组。

async function go(){
  try{
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto('www.webpage.com');

    const tds = await page.$$('td');
    const data = [];
    for (let i = 0; i < tds.length; i++){
      const td = tds[i];
      const tdcontent = await page.evaluate(td => td.innerText, td);
      if (tdcontent.length > 5) {
        data[i] = {"content": tdcontent};
      }
    }
    return data;
  } catch (e) {
     console.log(e);
  }
};

(async function main(){
  const returnedData = await go();
  console.log(returnedData.length);
})();

返回data.length0。对nodejs和async编程结构不熟悉。我认为是因为在返回.length之前记录了data吗?

如何以一种可以操纵数据并完成比较的方式返回数据?

2 个答案:

答案 0 :(得分:3)

在这种情况下,我尽量不使用page.$$。相反,我使用document.querySelectorAll并通过元素映射并提取文本。

这是修改后的代码:

const getTdData = async () => {
  try {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto("http://example.com");

    return page.evaluate(() => {
      // get all td elements
      const tdList = [...document.querySelectorAll("td")]; 
      return tdList.map(element => ({ content: element.textContent }));
    });
  } catch (e) {
    console.log(e);
  }
};

(async function main() {
  const returnedData = await getTdData();
  console.log(returnedData.length);
})();

答案 1 :(得分:0)

首先,您在page.$$()函数中缺少撇号。您应该将其更改为:

const tds = await page.$$( 'td' );

接下来,您尝试将不存在的变量传递给page.evaluate()。您可以通过传递tds[i]而不是td来解决此问题:

const tdcontent = await page.evaluate( td => td.innerText, tds[i] );

您的最终结果应如下所示:

const go = async () =>
{
    try
    {
        const browser = await puppeteer.launch();
        const page    = await browser.newPage();

        await page.goto( 'www.webpage.com' );

        const tds  = await page.$$( 'td' );
        const data = [];

        for ( let i = 0; i < tds.length; i++ )
        {
            const tdcontent = await page.evaluate( td => td.innerText, tds[i] );

            if ( tdcontent.length > 5 )
            {
                data[i] = { content : tdcontent };
            }
        }

        return data;
    }

    catch ( e )
    {
        console.log( e );
    }
};

( async function main ()
{
    const returnedData = await go();

    console.log( returnedData.length );
})();

如果仍然遇到问题,则可能要等到使用page.goto( ... , { waitUntil : 'networkidle0' })完全加载页面,或者等到使用page.waitForSelector()将有问题的元素添加到DOM中: / p>

await page.goto( 'www.webpage.com' , { waitUntil : 'networkidle0' });
...
await page.waitForSelector( 'td' );