我遇到了经典的异步/并发问题,人们偶尔会在Node.js中编写服务。我有一个对象从RDBM获取一些数据以响应请求,并在行提取完成时发出fin
事件(使用EventEmitter
)。
正如您所料,当服务的调用者对其进行几次几乎同时的调用时,行将以不可预测的顺序返回。对于与调用函数对生成它们的请求的理解不对应的行,会触发fin
事件。
这是我发生的事情(简化相关性):
var mdl = require('model.js');
dispatchGet: function(req, res, sec, params) {
var guid = umc.genGUID(36);
mdl.init(this.modelMap[sec], guid);
// mdl.load() creates returns a 'new events.EventEmitter()'
mdl.load(...).once('fin',
function() {
res.write(...);
res.end();
});
}
简单测试表明,mdl.guid
通常与guid
不对应。
我原以为在new events.EventEmitter()
函数中创建mdl.load()
可以通过为每个请求创建一个离散的EventEmitter
来解决这个问题,但显然情况并非如此;我认为对象持久性的相同规则适用于任何其他对象,而不管new
。
我是背景的C程序员:我当然可以提出自己的方案,将这些回复与他们的请求相关联,使用一些循环队列或散列方案。但是,我猜这个问题已经多次解决了。我的研究揭示了很多关于如何最好地处理这个问题的意见 - 各种排队实施,Futures
等。
我想知道的是,这里有什么最简单的方法来实现良好的异步流量控制?如果我不需要的话,我不想在某种依赖的大规模范式转变中陷入困境。是否存在相对简单,规范,明确的解决方案,和/或对哪个第三方模块最佳的广泛共识?
答案 0 :(得分:2)
可能是你的model.js
看起来像这样吗?
module.exports = {
init : function(model, guid) {
this.guid = guid;
...
}
};
你必须要知道你传递给module.exports
的对象有一个共享对象,从某种意义上说,运行require("model.js")
的每个其他模块都会收到一个引用同一个对象。
因此,每次运行mdl.init()
时,该对象的guid
属性都会更改,这可以解释您的注释“...一个简单的测试显示mdl.guid经常不符合guid“。
这实际上取决于你的确切实现,但我认为你想要使用一个类:
// model.js
var Mdl = function(model, guid) {
this.guid = guid;
};
Mdl.prototype.load = function() {
// instantiate and return a new EventEmitter.
};
module.exports = Mdl;
// app.js
var Mdl = require('model.js');
...
var mdl = new Mdl(this.modelMap[sec], guid);
mdl.load(...)