【问题标题】:How can I deal with asynchronous requests involving modal popups in Casperjs?如何处理涉及 Casperjs 中模式弹出窗口的异步请求?
【发布时间】:2019-08-17 17:29:23
【问题描述】:

尝试遍历打开模式弹出窗口的链接列表时,我遇到了 Javascript 的异步特性问题。我可以遍历链接,并且可以让 Casperjs 点击所有链接。弹出窗口打开得很好(我需要保存该弹出窗口的内容)。但是,我的代码导致 Casperjs 每隔几个链接就跳过一次——我怀疑这是因为延迟。我需要确保单击每个链接并保存每个弹出窗口。任何提示都非常感谢!

我知道 Casperjs 的 wait 和 waitForSelector 函数,但无论我把它们放在哪里——它仍然会跳过一些弹出窗口。我想这种行为的原因是延迟,但是增加/减少等待值和我告诉 casperjs 等待的地方没有帮助。

this.then(function(){
    x = 0;
        this.each(links,function(self,link){
        // I only need links that contain a certain string
        if(link.indexOf('jugyoKmkName')>=0) {
            var coursetitle = linktexts[x];
            this.clickLabel(linktexts[x], 'a');
               this.wait(2000, function() {
                var coursetitleSplit = coursetitle.split(' ');
                var courseid = coursetitleSplit[0];

                //this logs the title and id in a file. Works perfectly
                var line = courseid+'   '+coursetitle+' \\n';
                        fs.write('/myappdirectory/alldata.txt', line, 'a');

                //this logs the popup contents -- but it's completely out of sync
                var courseinfo = this.getElementInfo('.rx-dialog-large').html
                fs.write('/myappdirectory/'+courseid+'.html', courseinfo, 'w');
            }); 
        } 
        x++;
     }); 
});

我在这里记录了两件事——正在运行的日志文件中的链接文本(以及更多信息)。这很好——它正确地捕获了每个链接。链接文本包含一个唯一的 ID,我将其用作文件名来保存弹出内容。这只适用于每第 n 个弹出窗口 - 弹出内容和 id 不同步。

准确地说:列表中的前 10 个 id 是:

20000 -- 使用此 id 保存,但包含弹出窗口 20215 的数据 20160 -- 使用此 id 保存,但包含弹出窗口 20307 的数据 20211 -- 使用此 id 保存,但包含弹出窗口 20312 的数据 20214 ...等(已保存,但从列表下方的 ID 方式弹出) 20215 20225 20235 20236 20307 20308

显然,我需要文件 2000.html 来保存 ID 为 20000、20160 的内容为 20160 等的弹出窗口的内容。

【问题讨论】:

    标签: javascript casperjs


    【解决方案1】:

    大概this.each(links,...) 将同步运行回调而不是等待每个this.wait() 调用完成。相反,您需要等到将数据写入文件系统后再处理下一个链接。请考虑以下代码:

    this.then(function() {
      function processNthLink(i) {
        var self = this;
        var link = links[i];
    
        if (link.indexOf('jugyoKmkName')>=0) {
          var coursetitle = linktexts[i];
          self.clickLabel(linktexts[i], 'a');
          self.wait(2000, function() {
            var coursetitleSplit = coursetitle.split(' ');
            var courseid = coursetitleSplit[0]; 
            var line = courseid+'   '+coursetitle+' \\n';
            fs.write('/myappdirectory/alldata.txt', line, 'a'); 
            var courseinfo = self.getElementInfo('.rx-dialog-large').html
            fs.write('/myappdirectory/'+courseid+'.html', courseinfo, 'w');
    
            if (i < links.length) {
              processNthLink(i+1);
            }
          }); 
        } else if (i < links.length) {
          processNthLink(i+1);
        }
      }
    
      processNthLink(0);
    });
    

    在这种情况下,只有在超时和写入 FS 完成后才会处理下一个链接。如果链接不包含预期的字符串,则立即处理下一个链接。

    【讨论】:

    • 感谢您的快速回复!我明白了...但是,由于某种原因,现在单击不应单击的链接(似乎忽略了“link.indexOf('jugyoKmkName')> = 0”...我将尝试调试这个并标记你的答案是正确的。
    • 在函数 processNthLink 中将“this”替换为“casper”起到了作用——再次感谢。这帮助我现在对 Casperjs 有了更多的了解。非常感谢。
    猜你喜欢
    • 2018-04-27
    • 1970-01-01
    • 2022-01-19
    • 2018-09-30
    • 1970-01-01
    • 2018-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多