Node.js请求序列化的最简单方法

时间:2013-05-29 11:40:50

标签: javascript node.js concurrency

我遇到了经典的异步/并发问题,人们偶尔会在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等。

我想知道的是,这里有什么最简单的方法来实现良好的异步流量控制?如果我不需要的话,我不想在某种依赖的大规模范式转变中陷入困境。是否存在相对简单,规范,明确的解决方案,和/或对哪个第三方模块最佳的广泛共识?

1 个答案:

答案 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(...)