0

domのテストを行うために、zombie.jsライブラリを使用しています。このスクリプトがあります

Browser = require "zombie"
arr = new Array("http://yahoo.com", "http://google.com", "http://msn.com")
i = 0
while i < arr.length
    b = new Browser()
    b.visit arr[i], ->
        console.log b.text "title"
    b.close()
    i++

すべてが機能しますが、msn タイトルは 2 回しか記録されないため、while ループは配列の最後の項目を 2 回記録しています。私は問題が何であるかを見ることができないようですか?

4

3 に答える 3

2

ブラウザvisitが完了したときのコールバックを登録しています。その時点までに、ループは完了するまで実行されているため、変数bは最後に作成したブラウザーを指します。つまり、そのタイトルは、他のページのタイトルではなく、MSN のタイトルになります。これを修正するには、クロージャーを使用します。

Browser = require "zombie"
arr = new Array("http://yahoo.com", "http://google.com", "http://msn.com")
i = 0
createBrowser = (url) ->
    b = new Browser()
    b.visit url, -> console.log b.text "title"
    b.close()

while i < arr.length
    createBrowser(arr[i++])

これが機能するのは、作成するブラウザーごとに個別のスコープと、個別のブラウザー変数があるためです。

または、ZombieJS のvisit関数のコールバック引数を使用します。

Browser = require "zombie"
arr = new Array("http://yahoo.com", "http://google.com", "http://msn.com")
i = 0
while i < arr.length
    b = new Browser()
    b.visit arr[i], (e, myBrowser) ->
        console.log myBrowser.text "title"
    b.close()
    i++
于 2013-01-21T13:22:07.807 に答える
1

visitメソッドは非同期で、コールバック関数を使用します。つまり、visitロギングが発生する前に が 3 回呼び出されます。つまり、との呼び出しの間に console.log は実行されません。最後のコールバックが終了するまでに、「最後の」ブラウザ インスタンス (msn のインスタンス) を参照します。メソッドはコールバックの結果を渡す可能性があります。ドキュメントを確認してください。b.visitb.closebvisit

Browser = require 'zombie'

for url in ["foo", "bar", "baz"] # elegant way to loop lists in coffeescript
  b = new Browser
  b.visit url, (err, b) ->       # b given as argument masks the b in outer scope
    console.log b.text "title"
    b.close()
于 2013-01-21T13:10:37.783 に答える
1

あなたがやりたいことは次のようなものだと思います(警告、テストされていません!):

Browser = require "zombie"
sites = ['http://yahoo.com', 'http://google.com', 'http://msn.com']

process = (site) ->
  b = new Browser()
  b.visit site, () ->
    title = b.text title
    console.log title
    b.close()

process site for site in sites

私は自由にいくつかの部分を変更しましたが、まだ明確であることを願っています。

JavaScript (および CoffeeScript) には、慣れていない場合、奇妙なスコープ規則があります。期待どおりに機能させるには、通常、すべての作業を関数で行うのが最善だと思います。

zombie.js がどのように機能するかは正確にはわかりませんが、これは期待どおりに動作するはずです。

于 2013-01-21T13:27:55.637 に答える