似乎我想做的事情是不可能的,两种模式相冲突。为了最终达到我想要的效果,我将模块封装到一个类似数组的对象中,并使用一些事件方法将其传递给模块的对象,该对象继承了async-eventemitter
类。
所以,认为它是这样的...
- 我的自定义应用程序模块可以继承异步eventemitter模块,以便他们有
.on()
和.emit()
等方法。
- 我创建了一个自定义的数组项,这将允许我将事件传递给将会异步工作的模块。
我创建的代码(这是不完整或完善)...
// My private indexer for accessing the modules array (below) by name.
var module_dict = {};
// An array of my modules on my (express) app object
app.modules = [];
// Here I extended the array with easier ways to add and find modules.
// Haven't removed some code to trim down this. Let me know if you want the code.
Object.defineProperty(app.modules, 'contains', { enumerable: false, ... });
Object.defineProperty(app.modules, 'find', { enumerable: false, ... });
// Allows us to add a hook/(async)event to a module, if it exists
Object.defineProperty(app.modules, 'on', { enumerable: false, configurable: false, value: function(modulename, action, func) {
if (app.modules.contains(modulename)) {
var modu = app.modules.find(modulename);
if (modu.module && modu.module['on']) {
// This will pass on the event to the module's object that
// will have the async-eventemitter inherited
modu.module.on(action, func);
}
}
} });
Object.defineProperty(app.modules, 'once', { enumerable: false, configurable: false, value: function(modulename, action, func) {
if (app.modules.contains(modulename)) {
var modu = app.modules.find(modulename);
if (modu.on) {
modu.on(action, func);
}
}
} });
这就让我通过简单地调用类似如下的事件处理程序模块绑定... .on(module_name, event_name, callback)
app.modules.on('my_special_module_name', 'loaded', function(err, data, next) {
// ...async stuff, that then calls next to continue to the next event...
if (data.filename.endsWith('.jpg'))
data.dimensions = { width: 100, height: 100 };
next(err, data);
});
然后执行它,我会做这样的事情(快递)...
app.get('/foo', function(req, res, next) {
var data = {
filename: 'bar.jpg'
};
// Now have event handlers alter/update our data
// (eg, extend an object about a file with image data if that file is an image file).
my_special_module.emit('loaded', data, function(err, data) {
if (err) next(err);
res.send(data);
next();
});
});
再一次,这只是我做过的一个例子,所以我可能错过了上面我的副本中的某些内容,但实际上这是我最终使用的设计,它的工作方式像一种享受,我能够扩展数据在被推送到我的HTTP响应之前,不需要替换主[expressjs]对象的标准EventEmitter模型。
(例如,我添加图像数据,我们正在加载,我们是图像文件的文件。如果有人想代码,让我知道,我很乐意分享我做了什么)
还,我不能废除EventEmitter模型,因为我使用这个模块来附加模块化的crud函数。 –
在CPS中,你不能逃避嵌套的回调。有了承诺,您可以更线性地组织代码。使用生成器(yield),您可以编写同步代码。在任何情况下,当你走异步都没有回头路时,你基本上陷入了异步世界。 – elclanrs
事件监听器是**不**同步调用。 –