"然后"在CasperJS中真正意味着什么

ben*_*ree 97 javascript casperjs

我正在使用CasperJS通过网站自动执行一系列点击,完成表单,解析数据等.

Casper似乎被组织成一个then语句形式的预设步骤列表(参见他们的例子:http://casperjs.org/quickstart.html)但是不清楚是什么触发了实际运行的下一个语句.

例如,是否then等待所有待处理的请求完成?是否被injectJS视为待处理请求?如果我有一个then嵌套的语句 - 链接到open语句的末尾会发生什么?

casper.thenOpen('http://example.com/list', function(){
    casper.page.injectJs('/libs/jquery.js');
    casper.evaluate(function(){
        var id = jQuery("span:contains('"+itemName+"')").closest("tr").find("input:first").val();
        casper.open("http://example.com/show/"+id); //what if 'then' was added here?
    });
});

casper.then(function(){
    //parse the 'show' page
});
Run Code Online (Sandbox Code Playgroud)

我正在寻找CasperJS中流程如何工作的技术解释.我的具体问题是我的上一个then陈述(上图)在我的casper.open陈述之前运行而我不知道为什么.

NiK*_*iKo 93

then()基本上在堆栈中添加了一个新的导航步骤.一步是一个javascript函数,可以做两件事:

  1. 等待上一步 - 如果有 - 正在执行
  2. 等待请求的URL和相关页面加载

我们来看一个简单的导航场景:

var casper = require('casper').create();

casper.start();

casper.then(function step1() {
    this.echo('this is step one');
});

casper.then(function step2() {
    this.echo('this is step two');
});

casper.thenOpen('http://google.com/', function step3() {
    this.echo('this is step 3 (google.com is loaded)');
});
Run Code Online (Sandbox Code Playgroud)

您可以打印出堆栈中所有已创建的步骤,如下所示:

require('utils').dump(casper.steps.map(function(step) {
    return step.toString();
}));
Run Code Online (Sandbox Code Playgroud)

这给了:

$ casperjs test-steps.js
[
    "function step1() { this.echo('this is step one'); }",
    "function step2() { this.echo('this is step two'); }",
    "function _step() { this.open(location, settings); }",
    "function step3() { this.echo('this is step 3 (google.com is loaded)'); }"
]
Run Code Online (Sandbox Code Playgroud)

注意_step()CasperJS自动添加的功能,为我们加载网址; 当加载url时,将调用堆栈中可用的下一步 - 即step3()- .

定义导航步骤后,run()按顺序逐个执行:

casper.run();
Run Code Online (Sandbox Code Playgroud)

脚注:回调/监听器的东西是Promise模式的实现.

  • 是不是所谓的'堆栈'实际上是一个队列?这些步骤是按顺序执行的,如果它是堆栈我们不期望第3步,第2步,第1步? (5认同)

sta*_*cke 33

then() 只是注册了一系列步骤.

run() 它的运行函数,回调函数和监听器系列都是执行每一步的实际工作.

每当一个步骤完成,CasperJS将检查对3个标志:pendingWait,loadInProgress,和navigationRequested.如果这些标志中的任何一个是真的,那么什么都不做,直到稍后的时间(setInterval样式).如果这些标志都不为真,那么下一步将被执行.

从CasperJS 1.0.0-RC4开始,存在缺陷,在某些基于时间的情况下,在CasperJS有时间提升其中一个loadInProgress或多个navigationRequested标志之前,将触发"尝试下一步"方法.解决方案是在离开任何希望引发这些标志的步骤之前引发其中一个标志(例如:在要求a之前或之后提出标志casper.click()),也许是这样:

(注意:这只是说明性的,更像是psuedocode而不是正确的CasperJS形式......)

step_one = function(){
    casper.click(/* something */);
    do_whatever_you_want()
    casper.click(/* something else */); // Click something else, why not?
    more_magic_that_you_like()
    here_be_dragons()
    // Raise a flag before exiting this "step"
    profit()
}
Run Code Online (Sandbox Code Playgroud)

为了将该解决方案包装成单行代码,我blockStep()在这个github pull请求中引入了扩展,click()clickLabel()作为一种手段来帮助保证我们在使用时获得预期的行为then().查看有关更多信息,使用模式和最低测试文件的请求.

  • 先生,你赢了一千分.愿你的刀片永不沉闷. (3认同)