How to update the URL in “then*” function?

2019-09-03 07:26发布

问题:

I have below code snippet.

var admin_url = "http://www.sampledomain.com/";
var casper = require('casper').create();
casper.start();

casper.thenOpen(
    "http://www.test.com", {
        method: "post",
        data: {
            param1: "some data"
        }
    },
    function() {
        what_i_want = this.getPageContent().split("[")[1].split("]")[0]
        admin_url += what_i_want;
    }
);

casper.thenOpen(admin_url, function() {
    this.echo(this.getCurrentUrl());
});

casper.run();

I first post to http://www.test.com, then use the returned data, I try to modify the admin_url, which is my second URL that need to access. However, my testing shows that the second thenOpen method still got the old admin_url value and did not pick up the latest updated value (notice that I've updated it in the first thenOpen method). What's the reason of this issue and how to fix it?

回答1:

When you call thenOpen the admin_url is passed by value, but thenOpen itself is executed asynchronously. You can see it this way: You add some steps to the queue and when you call run, the queue begins to execute with the initial steps and their accompanying data. So you need to add your last thenOpen step dynamically to the queue when the admin_url is complete:

casper.thenOpen(
    "http://www.test.com", {
        method: "post",
        data: {
            param1: "some data"
        }
    }, function then() {
        whatIWant = this.getPageContent().split("[")[1].split("]")[0]
        admin_url += video_id;

        this.thenOpen(admin_url, function() {
            this.echo(this.getCurrentUrl());
        });
    }
);

casper.run();

There is also the possiblity to break thenOpen into its sub-functions and use admin_url as a global variable:

var admin_url = "...";
casper.thenOpen(
    "http://www.test.com", {
        method: "post",
        data: {
            param1: "some data"
        }
    },
    function() {
        what_i_want = this.getPageContent().split("[")[1].split("]")[0]
        admin_url += what_i_want;
    }
).then(function() {
    this.open(admin_url);
}).then(function() {
    this.echo(this.getCurrentUrl());
}).run();

It reduces the nesting which might be a good thing based on your preference.