例如,我见过这样的函数,使用起来很方便:
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'
实现此模式的最佳方法是什么?
"改进"为:
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);
})
这个怎么样?我使用 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);
})
这些被称为promises或Deferreds,在jQuery中被广泛使用。
jQuery 1.5 中引入的延迟对象是通过调用
jQuery.Deferred()
方法创建的可链接实用程序对象。它可以将多个回调注册到回调队列中,调用回调队列,并中继任何同步或异步函数的成功或失败状态。延迟对象是可链接的,类似于 jQuery 对象可链接的方式,但它有自己的方法。创建 Deferred 对象后,可以使用以下任何方法,方法是直接从对象创建链接,或者将对象保存在变量中并对该变量调用一个或多个方法。
有许多节点模块可以实现延迟。