5

例如,我见过这样的函数,使用起来很方便:

myFunction(data).
  success(function() { // success! }).
  fail(function() { // fail! });

我看不到如何实现这一点的明显方法。这是我查看 Node.js 文档后的悲伤尝试:

var EventEmitter = require('events').EventEmitter;
var testEmitter = function(x) {
  var e = new EventEmitter();

  if (x) {
    e.emit('success', 'got: ' + x);
  } else {
    e.emit('failure', 'no x passed')
  }

  return e;
}

显然,当您尝试调用它时,这将不起作用:

testEmitter('hello').
  success(console.log('success!')).
  failure(console.log('failure!'));

  // TypeError: Object #<EventEmitter> has no method 'success'

实现此模式的最佳方法是什么?

4

3 回答 3

9

这可以“改进”为:

var EventEmitter = require('events').EventEmitter;

var testEmitter = function(x) {
  var e = new EventEmitter();

  process.nextTick(function(){
    if (x) {
      e.emit('success', 'got: ' + x);
    } else {
      e.emit('failure', 'no x passed')
    }
   })

  var self = {};
  self.success = function(f) {
    e.on('success',f);
    return self;
  };
  self.failure = function(f) {
    e.on('failure',f);
    return self;
  };
  return self;
};

testEmitter("hello").success(function(results){
  console.log('success!',results);
}).failure(function(error){
  console.log('failure!' + error);
})
于 2013-11-05T23:36:10.480 回答
2

这个怎么样?我已经使用 process.nextTick 来模拟您想要在函数中执行的异步工作。

var EventEmitter = require('events').EventEmitter;

var testEmitter = function(x) {
  var e = new EventEmitter();

  process.nextTick(function(){
      if (x) {
        e.emit('success', 'got: ' + x);
      } else {
        e.emit('failure', 'no x passed')
      }
  })

  return e;
}

testEmitter("hello").on("success", function(results){
    console.log('success!' + results);
}).on("failure", function(error){
    console.log('failure!' + error);
})
于 2013-11-05T22:40:39.227 回答
1

这些被称为 promises 或Deferreds,它们在 jQuery 中被广泛使用。

jQuery 1.5 中引入的 Deferred 对象是通过调用该jQuery.Deferred()方法创建的可链接实用程序对象。它可以将多个回调注册到回调队列中,调用回调队列,并中继任何同步或异步函数的成功或失败状态。

Deferred 对象是可链接的,类似于 jQuery 对象可链接的方式,但它有自己的方法。创建 Deferred 对象后,您可以通过直接从对象创建链接或将对象保存在变量中并在该变量上调用一个或多个方法来使用以下任何方法。

许多实现 Deferreds 的节点模块

于 2013-11-05T19:43:52.587 回答