如何从 casper.start 或 casper.thenOpen 中调用外部函数
How to call an external function from within casper.start or casper.thenOpen
我正在尝试拆分以下代码,以便将回调函数存储在它自己的文件中。
var casper = require('casper').create();
casper.start("http://www.google.com/", function() {
this.echo(this.getTitle());
});
casper.run(); // "Returns Google"
在 this example 之后,我在名为 "getPageTitle.js";
的单独文件中定义了一个函数
function getPageTitle(casper) {
casper.echo(casper.getTitle());
}
exports.getPageTitle = getPageTitle;
并通过将 CasperJS object 直接传递到函数中来调用另一个名为 "main.js" 的文件中的函数;
var casper = require('casper').create();
var casperFunctions = require('./getPageTitle.js');
casper.start("http://www.google.com/", casperFunctions.getPageTitle(casper));
# Error: CasperError: Casper is not started, can't execute `getTitle()`
此外,如果我用 thenOpen()
调用替换上面的最后一行;
casper.start();
casper.thenOpen("http://www.google.com/", casperFunctions.getPageTitle(casper));
以上代码没有抛出错误; CasperJS 能够导航到该网站,但未返回页面标题 "Google"。
有人能解释一下为什么这与我预期的不一样吗?这似乎是一种将 CasperJS 在页面加载后调用的函数模块化的自然方式,但我在这里遗漏了什么吗?
casper.start("http://www.google.com/", casperFunctions.getPageTitle(casper));
不起作用,因为您将调用 casperFunctions.getPageTitle(casper)
的结果作为回调参数传递给 casper.start
我认为你应该可以这样做
casper.start("http://www.google.com/", casperFunctions.getPageTitle.bind(casper));
CasperJS 的执行是异步的。 start()
以及所有 then*()
和 wait*()
函数都是异步步函数。这意味着您只在诸如步骤内部的页面上。
当您查看 getPageTitle()
及其调用方式时,您应该注意到您没有将步进函数传递给 casper.start()
,而是立即调用 getPageTitle()
.那时,执行甚至还没有开始,因为一旦 run()
被调用,计划的步骤就开始执行。通过调用 getPageTitle()
,您正在尝试访问 about:blank 的标题,即 blank.
第一个版本:
function getPageTitle(casper) {
return function(){
casper.echo(casper.getTitle());
};
}
现在您将一个阶跃函数传递给 start()
,它将被异步计算。
第二个版本:
请记住,您可以在步进函数内使用 this
来引用 casper
。这是执行此操作的更好方法,因为您不需要显式传递引用:
function getPageTitle() {
return function(){
this.echo(this.getTitle());
};
}
并这样称呼它:
casper.start("http://www.google.com/", casperFunctions.getPageTitle());
第三个版本:
如果函数不需要任何参数,则不需要包装函数。可以直接传:
function getPageTitle() {
this.echo(this.getTitle());
}
并这样称呼它:
casper.start("http://www.google.com/", casperFunctions.getPageTitle);
我正在尝试拆分以下代码,以便将回调函数存储在它自己的文件中。
var casper = require('casper').create();
casper.start("http://www.google.com/", function() {
this.echo(this.getTitle());
});
casper.run(); // "Returns Google"
在 this example 之后,我在名为 "getPageTitle.js";
的单独文件中定义了一个函数function getPageTitle(casper) {
casper.echo(casper.getTitle());
}
exports.getPageTitle = getPageTitle;
并通过将 CasperJS object 直接传递到函数中来调用另一个名为 "main.js" 的文件中的函数;
var casper = require('casper').create();
var casperFunctions = require('./getPageTitle.js');
casper.start("http://www.google.com/", casperFunctions.getPageTitle(casper));
# Error: CasperError: Casper is not started, can't execute `getTitle()`
此外,如果我用 thenOpen()
调用替换上面的最后一行;
casper.start();
casper.thenOpen("http://www.google.com/", casperFunctions.getPageTitle(casper));
以上代码没有抛出错误; CasperJS 能够导航到该网站,但未返回页面标题 "Google"。
有人能解释一下为什么这与我预期的不一样吗?这似乎是一种将 CasperJS 在页面加载后调用的函数模块化的自然方式,但我在这里遗漏了什么吗?
casper.start("http://www.google.com/", casperFunctions.getPageTitle(casper));
不起作用,因为您将调用 casperFunctions.getPageTitle(casper)
的结果作为回调参数传递给 casper.start
我认为你应该可以这样做
casper.start("http://www.google.com/", casperFunctions.getPageTitle.bind(casper));
CasperJS 的执行是异步的。 start()
以及所有 then*()
和 wait*()
函数都是异步步函数。这意味着您只在诸如步骤内部的页面上。
当您查看 getPageTitle()
及其调用方式时,您应该注意到您没有将步进函数传递给 casper.start()
,而是立即调用 getPageTitle()
.那时,执行甚至还没有开始,因为一旦 run()
被调用,计划的步骤就开始执行。通过调用 getPageTitle()
,您正在尝试访问 about:blank 的标题,即 blank.
第一个版本:
function getPageTitle(casper) {
return function(){
casper.echo(casper.getTitle());
};
}
现在您将一个阶跃函数传递给 start()
,它将被异步计算。
第二个版本:
请记住,您可以在步进函数内使用 this
来引用 casper
。这是执行此操作的更好方法,因为您不需要显式传递引用:
function getPageTitle() {
return function(){
this.echo(this.getTitle());
};
}
并这样称呼它:
casper.start("http://www.google.com/", casperFunctions.getPageTitle());
第三个版本:
如果函数不需要任何参数,则不需要包装函数。可以直接传:
function getPageTitle() {
this.echo(this.getTitle());
}
并这样称呼它:
casper.start("http://www.google.com/", casperFunctions.getPageTitle);