2015-03-07 30 views
6

Örneğin: Bir sayfayı PhantomJS ile açtım, eşzamansız bir komut dosyasını (ör., Ajax) değerlendiriyorum. Başarılı olduğunda, hayali bağlamın (page.evaluate() dışında) asenkron işlemin bittiğini bilmesini istiyorum.Sayfa içeriğinden fantom bağlamındaki bir olayı dinlemenin bir yolu var mı?

Süreç tamamlandığında hayalet bağlamında sürekli olarak bekleyip kontrol etmek için setTimeout ve setInteval kullanmak istemiyorum.

cevap

14

Bu tam olarak onCallback and window.callPhantom() pair içindir. Eğer bir AJAX isteği gibi sayfa bağlamında bir zaman uyumsuz çağrı varsa

Yani, bunu yapabilirsiniz:

page.onCallback = function(data){ 
    console.log("finished: " + data.text); 
    phantom.exit(); 
}; 
page.evaluate(function(){ 
    var xhr = new XMLHttpRequest(); 
    xhr.open("GET", "/"); 
    xhr.onreadystatechange = function() { 
     var DONE = this.DONE || 4; 
     if (this.readyState === DONE){ 
      window.callPhantom({text: this.responseText}); 
     } 
    }; 
    xhr.send(); 
}); 

bu kullanmak için başka bir yol yapmak için üretime JavaScript çağrısı eklemektir Daha kolay test Bir web uygulaması yazıyorsanız, bir sayfa tam olarak yüklendiğinde belirten bir seçici bulmak bazen karmaşıktır.

finishOffPage(function callback(){ 
    if (typeof window.callPhantom === "function") { 
     window.callPhantom({type: "loadFinished"}); 
    } 
}); 

Sonra böyle testler yazabilirsiniz: Bu örnek nerede böyle bir şey olabilir olduğunu

page.onCallback = function(data){ 
    if (data.type === "loadFinished") { 
     // do some testing 
    } 
}; 
page.open(url); 

kolay böyle bir uygulamayı test yapmak için, sayfa JavaScript böyle bir şey olabilir Dinamik olarak eklenecek: wait for angular app to be fully rendered from phantom script

+0

Uygulamamı yapmak için Node.js'yi fantom ile birlikte kullanıyorum. Kullanıcılardan iki eşzamanlı istek olduğunu varsayalım. Her istek yukarıdaki kodu bir kez çalıştırır. İlk isteğin page.onCallback'inin ikinci isteğin window.callPhantom() öğesinden veri alması ihtimali var mıdır? –

+0

@MrCold Değil, aynı PhantomJS örneğini kullansanız bile her iki istek için aynı "sayfa" örneğini kullanmazsınız. Aynı "sayfa" örneğini kullansanız bile, yine de mümkün olmayacaktır, çünkü aynı etkinliğe iki etkinlik işleyicisini kaydettiremezsiniz. Sonuçları uygun yanıt nesnelerine yönlendirmek için muhtemelen bazı ara katman yazılımlarına ihtiyacınız olacaktır. –

+0

@ArtjomB. örneğinizde 'if (typeof window.callPhantom ==" İşlevi ") {' varsayalım varsa (typeof window.callPhantom === "function") {', böylece küçük harf" function ". – Grigorii