问题
CasperJS is awesome but it's not posting to my localhost what my console output is.
casper.wait(5000, function () {
casper.wait(1000, function () {
casper.then(function(){
for (var i = 0 ; i < 10; i++) {
var description = casper.fetchText(x('//*[@id="acDataId-local'+i+'"]/a')); //*[@id="acDataId-local0"]/a
console.log(description);
var target_date = casper.fetchText(x('//*[@id="dtDataId-local'+i+'"]/text()[1]'));
console.log(target_date);
var target_location = casper.fetchText(x('//*[@id="veDataId-local'+i+'"]'));
console.log(target_location);
console.log(i, description)
casper.then(function () {
casper.open('http://localhost:1337/events', {
method: 'post',
data: {
'description': description,
'target_date': target_date,
'target_location': target_location,
},
headers: {
"stuff":"stuff"
}
});
});
}
this.echo('POST ' + i );
});
});
});
casper.run();
Console.log is outputting exactly when I want but it is only posting the last item. I tried to add casper.wait in a variety of places but it didn't seem to help!
回答1:
All then*
and wait*
functions in CasperJS are asynchronous step functions and JavaScript has function-level scope.
This means that the for-loop is executed immediately and several then()
steps are scheduled to be executed after the for-loop is completely finished. At that point the function-level variables description
, target_date
, etc. will all have the value of the last i
and i
will be 10. Here is a general JavaScript example of that: JavaScript closure inside loops – simple practical example
You can either
change the two calls
casper.then()
andcasper.open()
to a single callcasper.thenOpen()
where the loop variables are passed to the function directly:casper.thenOpen('http://localhost:1337/events', { method: 'post', data: { 'description': description, 'target_date': target_date, 'target_location': target_location, }, headers: { "stuff":"stuff" } });
or "close" the variables for each iteration by introducing an IIFE:
for (var i = 0 ; i < 10; i++) { (function(){ var description = casper.fetchText(x('//*[@id="acDataId-local'+i+'"]/a')); //*[@id="acDataId-local0"]/a console.log(description); var target_date = casper.fetchText(x('//*[@id="dtDataId-local'+i+'"]/text()[1]')); console.log(target_date); var target_location = casper.fetchText(x('//*[@id="veDataId-local'+i+'"]')); console.log(target_location); console.log(i, description) casper.then(function () { casper.open('http://localhost:1337/events', { method: 'post', data: { 'description': description, 'target_date': target_date, 'target_location': target_location, }, headers: { "stuff":"stuff" } }); }); })(); }
来源:https://stackoverflow.com/questions/35568147/casperjs-posting-only-the-last-item-multiple-times-from-my-for-loop