有承诺的节点骑士

Node-horseman with promises

我正在尝试在 horseman 的 evalute 函数中使用 promises。一个简单的例子:

var Horseman = require('node-horseman');
var horseman = new Horseman();

horseman
  .open('http://google.com')
  .evaluate(function() {
    var promise = new Promise(function(resolve,reject){
      setTimeout(function(){resolve("Hello")},2000);  
    });
    return promise;
  })
  .then(function(mesg){
    console.log(mesg);
  })
  .close();

我希望解析值 "Hello" 传递给下一个 then 函数作为 mesg 参数 when承诺已兑现,但我收到以下错误:

Unhandled rejection fn
evaluate

global code
evaluateJavaScript@[native code]
evaluate@phantomjs://platform/webpage.js:390:39

我是不是漏掉了什么?

PhantomJS 进出浏览器的通信渠道非常有限。它必须基本上通过基于文本的路径发送所有内容,因此它必须序列化它发送的内容,并反序列化输出的内容。

您可以发送 "in" 一个要在浏览器的 JS 上下文中执行的函数,因为它只是将其转换为字符串。但是出来的东西不能是一个承诺,因为你失去了包裹在它周围的整个对象。您只能 return 标量值和原始对象。如果您查看模块 home page 中提供的示例,原始对象是 returned:

.evaluate( function(selector){
  // Trimmed for clarity...
  return {
    height : $( selector ).height(),
    width : $( selector ).width()
  }
}, '.thumbimage')

Node-horseman 确实有一个异步操作模式,但不是 return 承诺,你必须调用一个 done() 函数,你要求将其作为参数提供给你的函数:

.evaluate(function(ms, done){
    var start = Date.now();
    setTimeout(function() {
        done(null, Date.now() - start);
    }, ms);
}, 100)

来自 evaluate() 的 return 值已经是一个承诺。您不需要 return 自己的一个。您只需要做任何您想要的异步工作,然后用您的结果值调用 done()