Используйте Кошмар.js без синтаксиса ES6 и выхода
Я построил простой узловой скрипт, используя nightmare.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();
}
Я хочу запустить это в среде, использующей более старую версию node, которая не поддерживает функции ES6. На странице github нет примеров, как это сделать без ключевого слова "yield".
Я нашел пример использования без синтаксиса ES6 здесь: Webscraping with nightmare
Я написал это так:
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
});
1 ответ:
Документы ужасны, но, похоже, что кошмар основан на thenables. Я также не нашел много информации об интерфейсе обратного вызова, но это все равно привело бы к пирамиде отступов.
Поэтому лучше всего использовать promises, просто выберите любую библиотеку, которая примерно соответствует стандарту 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 });