Используйте Nightmare.js без синтаксиса ES6 и yield

Я создал простой скрипт node, используя кошмар.js для очистки веб-сайтов.

var Nightmare = require('nightmare');
var vo = require('vo');

vo(run)(function(err, result) {
    if (err) throw err;
});

function *run() {
    var x = Date.now();
    var nightmare = Nightmare();
    var html = yield nightmare
    .goto('http://google.com')
    .evaluate(function() {
        return document.getElementsByTagName('html')[0].innerHTML;
    });

    console.log("done in " + (Date.now()-x) + "ms");
    console.log("result", html);

    yield nightmare.end();
}

Я хочу запустить это в среде, используя более старую версию узла, которая не поддерживает функции ES6. На странице github нет примеров того, как это сделать без ключевого слова yield.

Я нашел пример использования без синтаксиса ES6 здесь: веб-скрейпинг с кошмаром

Я написал это так:

var night = new Nightmare()
.goto('http://www.google.com')
.evaluate(function () {
  return document.getElementsByTagName('html')[0].innerHTML;
},function (html) {
   console.log("result", html);
  }
)
.run(function (err, nightmare) {
  if (err) return console.log(err);
  console.log('Done!');
});

Он не падает, но функция регистрации результатов никогда не вызывается.

С синтаксисом yield получить возвращаемое значение от "evaluate" довольно просто, но без него я не нашел никакого способа сделать это.

ОБНОВЛЕНИЕ Написал это благодаря принятому ответу и его комментариям. Он использует «Q» и работает в версиях узлов до 0.12:

var Nightmare = require('nightmare');

var Promise = require('q').Promise;

var x = Date.now();
var nightmare = Nightmare();
Promise.resolve(nightmare
  .goto('http://google.com')
  .evaluate(function() {
      return document.getElementsByTagName('html')[0].innerHTML;
})).then(function(html) {
    console.log("done in " + (Date.now()-x) + "ms");
    console.log("result", html);
    return nightmare.end();
}).then(function(result) {

}, function(err) {
   console.error(err); // notice that `throw`ing in here doesn't work
});

person Rayjax    schedule 15.09.2015    source источник
comment
Использование babel-node может быть более простым решением, в зависимости от вашего варианта использования. . По сути, это оболочка, которая транспилирует код ES6 в ES5 перед его запуском.   -  person Maël Nison    schedule 16.09.2015


Ответы (1)


Документы ужасны, но кажется, что Nightmare основан на анимациях. Я также не нашел много информации об интерфейсе обратного вызова, но это все равно привело бы к пирамиде отступов.

Поэтому лучше всего использовать обещания, просто выберите любую библиотеку, которая примерно соответствует стандарту ES6 (все они могут использоваться в средах, отличных от ES6, как Что ж).

Вы можете легко преобразовать код линейного генератора в цепочку обещаний, просто заменив каждый yield вызовом then:

var Nightmare = require('nightmare');
var Promise = require('…');

var x = Date.now();
var nightmare = Nightmare();
Promise.resolve(nightmare
  .goto('http://google.com')
  .evaluate(function() {
      return document.getElementsByTagName('html')[0].innerHTML;
})).then(function(html) {
    console.log("done in " + (Date.now()-x) + "ms");
    console.log("result", html);
    return nightmare.end();
}).then(function(result) {
    …
}, function(err) {
   console.error(err); // notice that `throw`ing in here doesn't work
});
person Bergi    schedule 15.09.2015
comment
Какую библиотеку из списка вы использовали именно в этом примере? Я пытался с q без успеха - person Rayjax; 16.09.2015
comment
Ах, Q имеет устаревшие соглашения о вызовах (это была одна из первых библиотек). Вам нужно будет сделать Q.Promise вместо Promise и Q вместо Promise.resolve. - person Bergi; 16.09.2015