简体   繁体   中英

how to change a global variable inside in casper.js

Title looks pretty straight forwoard but I am having difficulties with it.

casper.then(function () {
        var tempname = casper.fetchText(x('//*[@id="root"]/div[4]/div/div/div[1]/div/div/div[2]/div/div[2]/div/h1'));

    oc[a]=tempname;
    console.log(" this works: "+oc[a]); //oc array vanishes
});
console.log("*******this doesnt******** " + oc[1]);

in this code piece inside the function I think it creates another variable called oc[] but this time it is local variable. How can I change the global variable oc[] just like in c++ . I defined var oc = [] at global scope but when I try to change global one doesnt change at all. to show you that I declared my oc array at global scope here is the code below

// JavaScript source code
// JavaScript source code
phantom.casperPath = 'C:/casperjs';
phantom.injectJs(phantom.casperPath + '/bin/bootstrap.js');


var casper = require('casper').create({
    pageSettings: {
        loadImages: false,//The script is much faster when this field is set to false
        loadPlugins: false,
        userAgent: 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36'
    }

});

//First step is to open angellist
casper.start().thenOpen("https://angel.co/login", function () {
    console.log("angel website opened");
});


//lets fill username and pass login 
casper.then(function () {
    console.log("Login using username and password");
    this.evaluate(function () {
        document.getElementById("user_email").value = "email";
        document.getElementById("user_password").value = "pass";
        document.getElementsByName("commit")[0].click();
    });
});



//go to people page

casper.then(function () {
    casper.thenOpen('https://angel.co/people').viewport(1200,800);

});



//click to profession in this case it is data scientist
casper.then(function () {

    this.click('#data-scientist');
    casper.wait(1000);

});
var bitisik = [];
var oc = [];


//wait to load


//now lets get people names
casper.then(function () {
    var accounts = "";
    var howmanylinks=0;
    var x = require('casper').selectXPath;
    var fs = require('fs');


    var personCount = this.evaluate(function(){ return document.getElementsByClassName("dpl36 people-list frw44 row _a _jm").length;});
    var anglinks = [];

    //counts the people on the page. Default is 12 for our website
    for(var b=0; b<personCount; b++){

        anglinks[b]= this.evaluate(function(arg){

            return  document.getElementsByClassName("name")[arg].getElementsByTagName('a')[0].href;},b);


    }

    for(var a=0; a<personCount; a++) {
        casper.thenOpen(anglinks[a]).viewport(1200,800);


        (casper.then( function () {
            howmanylinks = this.evaluate(function(){
                return document.getElementsByClassName('darkest dps64 profiles-show fls45 links _a _jm')[0].getElementsByTagName('a').length;
            });
            //console.log(howmanylinks);
        }),howmanylinks);

        //everything above looks correct to me


        casper.then(function () {
            var tempname = casper.fetchText(x('//*[@id="root"]/div[4]/div/div/div[1]/div/div/div[2]/div/div[2]/div/h1'));

            oc[a]=tempname;
            console.log(" this works: "+oc[a]); //oc array vanishes
        });
        console.log("*************** " + oc[1]);


        (casper.then(function (arg) {
            for (var i = 0; i < howmanylinks; i++) {

                var accounta = this.evaluate(function(arg){ return  document.getElementsByClassName('darkest dps64 profiles-show fls45 links _a _jm')[0].getElementsByTagName('a')[arg].href;},i);
                bitisik[a] = bitisik[a] + accounta;
                console.log(accounta);
            }
        }),a);





    }

    (casper.then(function () {

    }),oc,bitisik);




});

//mandatory stuff to run the js
casper.then(function () {

    casper.exit();
});
casper.run();

Your code executes in a different order:

The function passed to the then method is not immediately executed, but later, asynchronously. So oc[a] is not immediately executed either.

Your console.log(oc[1]) however, is executed immediately, well before oc[1] receives a value.

Please also note that therefore it is also wrong to reference a in that asynchronous function, because by the time it executes, your a will already have reached its maximum value. Your for loop will finish before the function in the then method executes for the first time.

So in the end, oc[1] will never get a value at all.

Note that this issue is also present with other code you have in other then functions.

Now, to initialise the oc[] array, pass a as an argument, for instance like this:

    function setOc(a) {
        var tempname = casper.fetchText(x('//*[@id="root"]/div[4]/div/div/div[1]/div/div/div[2]/div/div[2]/div/h1'));

        oc[a]=tempname;
        console.log(" this works: "+oc[a]); //oc array vanishes
        if (a === personCount - 1) {
            // oc is initialised, do anything you want from here.
        }
    };
    casper.then(setOc.bind(a));

Alternatively, you could put a loop on a inside the above function, and things will be easier.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM