在 Casperjs 中循环访问 URL
Looping over URLs in Casperjs
我正在尝试使用 Casperjs 按顺序打开几个 URL。
这是我实际代码的简化版本。
casper = require('casper').create()
casper.start()
casper.then () ->
items = ['http://www.google.com', 'http://www.yahoo.com']
for item, idx in items
this.open item
this.then ((idx) ->
() ->
this.capture idx + '.png')(idx)
casper.run()
在我的实际代码中,项目数组是在运行时生成的。我希望此代码将提供 google.com 和 yahoo.com 的屏幕截图,但实际上这两个屏幕截图最终都是 yahoo.com。我觉得这与在循环内创建闭包有关,但我看不出如何。当调用 open
时,item
引用特定的字符串。我永远不会结束它,是吗?
问题在于 casper.open
没有添加步骤,因此它不是异步的(如 thenOpen
)。它立即在外部 then
内部执行。但是下面的then
是异步的,所以它的步骤被添加到当前步骤之后执行(外部then
)。两个 open
都执行了,但是两个 then
的回调都在最后一个 open
.
之后执行
因此解决方案是使用 thenOpen
作为组合的异步步骤。直接解决方案有一个小问题:
CoffeeScript is a little language that compiles into JavaScript.
这意味着 JavaScript 存在误解。这是一个:JavaScript closure inside loops – simple practical example
for item, idx in items
行仍然是 for loop in JavaScript。 JavaScript 具有函数级别范围,casper.then
是一个异步步骤函数,这意味着所有 casper.then
调用的回调在循环 运行 完全通过(更准确地说当前步骤完成后或调用 casper.run
后),但立即执行 casper.open
。
解决方案:将 casper.open
和 casper.then
合并为 casper.thenOpen
并通过 IIFE 传递 item
和 idx
以便它们在每次迭代中固定:
for item, idx in items
((item, idx) ->
casper.thenOpen item, () ->
this.capture idx + '.png'
)(item, idx)
或使用Array.prototype.forEach
:
items.forEach (item, idx) ->
casper.thenOpen item, () ->
this.capture idx + '.png'
我正在尝试使用 Casperjs 按顺序打开几个 URL。
这是我实际代码的简化版本。
casper = require('casper').create()
casper.start()
casper.then () ->
items = ['http://www.google.com', 'http://www.yahoo.com']
for item, idx in items
this.open item
this.then ((idx) ->
() ->
this.capture idx + '.png')(idx)
casper.run()
在我的实际代码中,项目数组是在运行时生成的。我希望此代码将提供 google.com 和 yahoo.com 的屏幕截图,但实际上这两个屏幕截图最终都是 yahoo.com。我觉得这与在循环内创建闭包有关,但我看不出如何。当调用 open
时,item
引用特定的字符串。我永远不会结束它,是吗?
问题在于 casper.open
没有添加步骤,因此它不是异步的(如 thenOpen
)。它立即在外部 then
内部执行。但是下面的then
是异步的,所以它的步骤被添加到当前步骤之后执行(外部then
)。两个 open
都执行了,但是两个 then
的回调都在最后一个 open
.
因此解决方案是使用 thenOpen
作为组合的异步步骤。直接解决方案有一个小问题:
CoffeeScript is a little language that compiles into JavaScript.
这意味着 JavaScript 存在误解。这是一个:JavaScript closure inside loops – simple practical example
for item, idx in items
行仍然是 for loop in JavaScript。 JavaScript 具有函数级别范围,casper.then
是一个异步步骤函数,这意味着所有 casper.then
调用的回调在循环 运行 完全通过(更准确地说当前步骤完成后或调用 casper.run
后),但立即执行 casper.open
。
解决方案:将 casper.open
和 casper.then
合并为 casper.thenOpen
并通过 IIFE 传递 item
和 idx
以便它们在每次迭代中固定:
for item, idx in items
((item, idx) ->
casper.thenOpen item, () ->
this.capture idx + '.png'
)(item, idx)
或使用Array.prototype.forEach
:
items.forEach (item, idx) ->
casper.thenOpen item, () ->
this.capture idx + '.png'