0

我正在尝试在每行都有一个操作链接按钮的网格中进行迭代。我需要单击此按钮并返回网格并单击下一行的按钮。

请参阅 CasperJS 脚本:

for(var i=1; i<lines.length; i++) {

    var element = this.getElementInfo(x('//*[@id="elx"]/tbody/tr[' + i +']/td[1]'));
    var item = x('//*[@id="gdvConsulta"]/tbody/tr[' + i +']/td[3]/a');

    var model = {
        'custom': element.text,
        'item': item.text
    };

    // Click on item
    casper.click(item);
    this.waitForSelector(x('//*[@id="grid"]'),
        function pass () {
            utils.dump('ok');
            var backbutton = x('//*[@id="back"]/a');

            casper.click(backbutton);
        },
        function fail () {
            utils.dump('error');
        }
    );

    utils.dump('done line');
}

注意:在单击我的第一次循环之前,已为所有行打印了“完成行”消息。

如何在waitForSelector()不进行下一次迭代的情况下制作真实的?

4

1 回答 1

1

您不恰当地混合了同步和异步函数。您可以使用循环,因为您事先知道迭代次数,但问题可能是您item甚至在waitForSelector()执行第一步之前都单击了每个。

所有then*()wait*()函数都是异步步进函数。通过调用它们,您可以安排在当前步骤之后执行的步骤。您需要在如下步骤中包装同步代码:

for(var i=1; i<lines.length; i++) {
    (function(i){
        casper.then(function(){
            var element = this.getElementInfo(x('//*[@id="elx"]/tbody/tr[' + i +']/td[1]'));
            var item = x('//*[@id="gdvConsulta"]/tbody/tr[' + i +']/td[3]/a');

            // Click on item
            casper.click(item);
        });


        casper.waitForSelector(x('//*[@id="grid"]'),
            function pass () {
                utils.dump('ok');
                var backbutton = x('//*[@id="back"]/a');

                casper.click(backbutton);
                utils.dump('done line');
            },
            function fail () {
                utils.dump('error');
            }
        );
    })(i);
}

请注意,您需要将i变量包含在循环中,因为循环内部是异步执行的,所有i迭代的引用都将指向最后一个可能的. 在此处查看更多信息:循环内的 JavaScript 闭包——简单实用的示例i

于 2015-07-23T20:25:08.907 回答