Nodejs Puppeteer等待完成循环中的所有代码

时间:2018-06-18 14:55:01

标签: node.js for-loop asynchronous puppeteer

我正在使用木偶戏来废弃一个网页。在这个网页中,我输入了一些文字,然后点击提交按钮。单击后,页面将返回包含结果的表格。我希望在匹配'somevar'时得到这些表格结果。 问题是:for在循环之前没有完成所有功能。它不是填充输入并首先得到结果,而是已经进入下一个循环并再次填充输入,导致类似:'test1test2'

如何在循环之前执行内部执行所有函数?

callPup();

异步函数callPup(){

'use strict';

const puppeteer = require('puppeteer');

const textos = ['test1','test2'];

(async() => {
    const browser = await puppeteer.launch({headless: false});
    const page = await browser.newPage();

    await page.goto('http://localhost/teste.html');     

    await page.waitForSelector('#input1').then(funcOk());


    async function funcOk(){            
        for (let i = 0; i < textos.length; i++) {                       

            await page.type('#input1', textos[i]);

            await page.keyboard.press('Enter');                 

            /*get table results*/
            const data = page.evaluate(() => {
                const tds = Array.from(document.querySelectorAll('table tr td a'))
                return tds.map(a => {
                    var txt = a.innerHTML;
                    return txt.replace(/<a [^>]+>[^<]*<\/a>/g, '').trim();
                });
            });
            /*get table results*/

            /*get only valid results*/
            let j = 0;
            for (let z = 0; z < data.length; z++) {
                if(data[z] == someVar[i].num.toString()){
                    j = j + 1;          
                }
                if(j <= 14){
                    console.log(data[z]);
                    j = j + 1;
                }
            }
            /*get only valid results*/
        }           
    }

})();   

}

2 个答案:

答案 0 :(得分:1)

您可以使用Promise以串行方式同步运行循环,只使用像async这样的库会更容易。尝试使用eachSeries https://caolan.github.io/async/docs.html#eachSeries

    function funcOk(){            
        async.eachSeries(textos, async (text) => {                     

            await page.type('#input1', text);

            await page.keyboard.press('Enter');                 

            /*get table results*/
            const data = page.evaluate(() => {
                const tds = Array.from(document.querySelectorAll('table tr td a'))
                return tds.map(a => {
                    var txt = a.innerHTML;
                    return txt.replace(/<a [^>]+>[^<]*<\/a>/g, '').trim();
                });
            });
            /*get table results*/

            /*get only valid results*/
            let j = 0;
            for (let z = 0; z < data.length; z++) {
                if(data[z] == someVar[i].num.toString()){
                    j = j + 1;          
                }
                if(j <= 14){
                    console.log(data[z]);
                    j = j + 1;
                }
            }
            /*get only valid results*/

            return Promise.resolve()
        })
    }

答案 1 :(得分:0)

我认为不是:

await page.waitForSelector('#input1').then(funcOk());

你想这样做:

await page.waitForSelector('#input1'); await funcOk();

在第一种情况下,在启动waitForSelector()之前,您实际上并没有等待funcOk()。您也可以await page.waitForSelector('#input1').then(() => funcOk);。我更喜欢await方法。