我在CasperJS脚本中遇到以下范围问题。传递给casper.thenOpenAndEvaluate()时,baseTargetUrl未定义。为什么这样,我该如何解决?
var baseTargetUrl;
.....
casper.then(function() {
baseTargetUrl = this.evaluate(function() {
return __utils__.getElementByXPath('//*[@id="wrapper"]/div[1]/a[2]')["href"];
});
console.log('logging: '+baseTargetUrl); // works
});
casper.thenOpenAndEvaluate(baseTargetUrl ,function() { //baseTargetUrl is undefined here
var test = document.querySelector('myselector');
//do other stuff
});
答案 0 :(得分:3)
如您所知,我们无法从外部异步调用中获取变量。这看起来有点哈哈,但这是我现在最好的......
var baseTargetUrl;
.....
casper.then(function() {
baseTargetUrl = this.evaluate(function() {
return __utils__.getElementByXPath('//*[@id="wrapper"]/div[1]/a[2]')["href"];
});
console.log('logging: '+baseTargetUrl); // works
this.thenOpenAndEvaluate(baseTargetUrl ,function() { // 'this' being the instance of casper
var test = document.querySelector('myselector');
//do other stuff
});
});
答案 1 :(得分:1)
处理此问题的常用方法(有充分理由)是使用promise。
Promise有许多不同的实现。很多框架都有自己的承诺,比如jQuery和AngularJS。还有独立的承诺框架,例如Q
。
Promise是一种通过解析值来链接方法的方法。解决后,将调用链中的下一个函数。
当您使用Q时,您的代码可能如下所示:
var baseTargetUrl = Q.defer();
.....
casper.then(function() {
var value;
baseTargetUrl.resolve(value = this.evaluate(function() {
return __utils__.getElementByXPath('//*[@id="wrapper"]/div[1]/a[2]')["href"];
}));
console.log('logging: ' + value); // works
});
baseTargetUrl.then(function (value) {
casper.thenOpenAndEvaluate(value, function () { // value contains the result of the call above
var test = document.querySelector('myselector');
//do other stuff
});
});
Promise是一种处理异步代码的方法,可以防止它成为意大利面,保持理智。
在这种小情况下,简单地嵌套函数也可能是你的解决方案。
var baseTargetUrl;
.....
casper.then(function() {
baseTargetUrl = this.evaluate(function() {
return __utils__.getElementByXPath('//*[@id="wrapper"]/div[1]/a[2]')["href"];
});
console.log('logging: '+baseTargetUrl); // works
casper.thenOpenAndEvaluate(baseTargetUrl ,function() { //baseTargetUrl is no longer undefined, it's a closure now
var test = document.querySelector('myselector');
//do other stuff
});
});
答案 2 :(得分:1)
如何使用waitFor?
var baseTargetUrl;
casper.then(function() {
baseTargetUrl = this.evaluate(/**/);
});
casper.waitFor(function() {
return typeof baseTargetUrl !== "undefined";
}, function() {
var test = document.querySelector('myselector');
// ...
});
答案 3 :(得分:0)
这对我来说很有用:
var dre_num = "12345678"; // global
casper.getdre = function() {
return dre_num;
}
casper.setdre = function(str) {
dre_num = str;
}
casper.then(function(){
this.setdre("01833946");
});
casper.then(function(){
this.echo("dre_num : " + this.getdre());
});