J'essaye de diviser le code suivant de telle sorte que la fonction de rappel qui est stockée dans son propre fichier.

var casper = require('casper').create();
casper.start("http://www.google.com/", function() {
    this.echo(this.getTitle());
});
casper.run(); // "Returns Google"

Suite à cet exemple, je définis une fonction dans un fichier séparé appelé "getPageTitle.js";

function getPageTitle(casper) {
    casper.echo(casper.getTitle());
}
exports.getPageTitle = getPageTitle;

Et appelez la fonction dans un autre fichier appelé "main.js" en passant l'objet CasperJS directement dans la fonction;

var casper = require('casper').create();
var casperFunctions = require('./getPageTitle.js');
casper.start("http://www.google.com/", casperFunctions.getPageTitle(casper));
# Error: CasperError: Casper is not started, can't execute `getTitle()`                  

De plus, si je remplace la dernière ligne ci-dessus par un appel thenOpen();

casper.start();
casper.thenOpen("http://www.google.com/", casperFunctions.getPageTitle(casper));

Le code ci-dessus ne génère pas d'erreurs; CasperJS est capable de naviguer vers le site Web, mais le titre de la page "Google" n'est pas renvoyé.

Quelqu'un pourrait-il s'il vous plaît expliquer pourquoi cela ne se comporte pas comme prévu. Cela semble être un moyen naturel de modulariser les fonctions que CasperJS appellerait une fois les pages chargées, mais est-ce que je manque quelque chose ici?

1
JSB 22 juil. 2015 à 17:17

2 réponses

Meilleure réponse

L'exécution de CasperJS est asynchrone. start() et toutes les fonctions then*() et wait*() sont des fonctions pas à pas asynchrones. Cela signifie que vous êtes uniquement sur la page à l'intérieur d'une telle étape.

Quand vous regardez votre getPageTitle() et comment il est appelé, vous devriez remarquer que vous ne passez pas une fonction d'étape dans casper.start(), mais que vous appelez immédiatement getPageTitle(). À ce moment-là, l'exécution n'a même pas commencé, car les étapes planifiées commencent à s'exécuter dès que run() est appelé. En appelant getPageTitle(), vous essayez d'accéder au titre de about: blank qui est vide .

Première version:

function getPageTitle(casper) {
    return function(){
        casper.echo(casper.getTitle());
    };
}

Vous passez maintenant une fonction step dans start() qui sera évaluée de manière asynchrone.

Deuxième version:

Gardez à l'esprit que vous pouvez utiliser this dans une fonction d'étape pour faire référence à casper. C'est une meilleure façon de le faire, car vous n'avez pas besoin de passer la référence explicitement:

function getPageTitle() {
    return function(){
        this.echo(this.getTitle());
    };
}

Et appelez-le comme ceci:

casper.start("http://www.google.com/", casperFunctions.getPageTitle());

Troisième version:

Si la fonction n'a pas besoin d'arguments, alors vous n'avez pas besoin d'une fonction wrapper. Vous pouvez le passer directement:

function getPageTitle() {
    this.echo(this.getTitle());
}

Et appelez-le comme ceci:

casper.start("http://www.google.com/", casperFunctions.getPageTitle);
2
Artjom B. 22 juil. 2015 à 14:57
casper.start("http://www.google.com/", casperFunctions.getPageTitle(casper));

Ne fonctionne pas, car vous transmettez le résultat de l'appel de casperFunctions.getPageTitle(casper) comme paramètre de rappel à casper.start

Je pense que vous devriez pouvoir le faire à la place

casper.start("http://www.google.com/", casperFunctions.getPageTitle.bind(casper));
1
Jaromanda X 22 juil. 2015 à 14:25