如何在后续调用中重用casperJS调用中填充的变量?

时间:2014-01-05 11:20:53

标签: javascript casperjs

我在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

});

4 个答案:

答案 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());
});