2015-03-07 26 views

risposta

14

Questo è esattamente ciò che è lo onCallback and window.callPhantom() pair.

Quindi, se si dispone di una chiamata asincrona nel contesto di pagina come una richiesta AJAX, si può fare questo:

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(); 
}); 

L'altro modo di utilizzare questo è quello di aggiungere la chiamata alla vostra produzione JavaScript per rendere test più facile. Se stai scrivendo un'applicazione web a volte è complicato trovare un selettore che denota quando una pagina è completamente caricata. Per fare il test di tale applicazione più semplice, si può avere qualcosa di simile nella pagina JavaScript:

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

Quindi è possibile scrivere i test in questo modo:

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

Questo è un esempio in cui una cosa del genere può essere aggiunto dinamicamente: wait for angular app to be fully rendered from phantom script

+0

Sto usando Node.js insieme a phantom per rendere la mia app. Supponiamo che ci siano due richieste simultanee da parte degli utenti. Ogni richiesta esegue il codice precedente una volta. C'è qualche possibilità che page.onCallback della prima richiesta riceva dati da window.callPhantom() della seconda richiesta? –

+0

@MrCold Non proprio, perché non si utilizzerà la stessa istanza 'page' per entrambe le richieste anche se si utilizza la stessa istanza di PhantomJS. Anche se usi la stessa istanza di 'page', non sarà ancora possibile, perché non puoi registrare due gestori di eventi sullo stesso evento. Probabilmente avrai bisogno di qualche middleware per indirizzare i risultati agli oggetti di risposta appropriati. –

+0

@ArtjomB. nel tuo esempio 'if (typeof window.callPhantom ==" Function ") {' supponiamo di essere 'if (typeof window.callPhantom ===" function ") {', quindi minuscolo "function". – Grigorii