【问题标题】:Use Nightmare.js without ES6 syntax and yield使用没有 ES6 语法的 Nightmare.js 和 yield
【发布时间】:2015-12-11 21:16:49
【问题描述】:

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

我想在使用不支持 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”中获取返回值非常简单,但是没有它,我没有找到任何方法。

更新 感谢接受的答案及其 cmets。它使用“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
});

【问题讨论】:

  • 使用babel-node 可能是一个更简单的解决方案,具体取决于您的用例。它基本上是在运行之前将 ES6 代码转换为 ES5 的包装器。

标签: javascript node.js ecmascript-6 yield nightmare


【解决方案1】:

文档很糟糕,但 Nightmare 似乎是基于 thenables 的。我也没有找到太多关于回调接口的信息,但这无论如何都会导致缩进金字塔。

所以最好的办法是使用 Promise,只需选择大致遵循 ES6 标准的any library(它们都可以在非 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
});

【讨论】:

  • 您在这个精确的示例中使用了列表中的哪个库?我尝试使用“q”但没有成功
  • 啊,Q 有遗留调用约定(它是最早的库之一)。您需要使用Q.Promise 而不是PromiseQ 而不是Promise.resolve
猜你喜欢
  • 2016-02-17
  • 2016-06-12
  • 2018-06-03
  • 2015-04-18
  • 1970-01-01
  • 1970-01-01
  • 2017-12-12
  • 2014-12-28
  • 2019-04-04
相关资源
最近更新 更多