0

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

我想知道的是,这里最好的异步流控制最简单的方法是什么?如果我不需要的话,我不想深入了解一些依赖的巨大范式转变。是否存在相对简单、规范、明确的解决方案和/或关于哪个第三方模块最好的广泛共识?

4

1 回答 1

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(...)
于 2013-05-29T11:54:48.630 回答