3

我有一组文件,module1.js、module2.js、module3.js,每个文件都包含一个返回对象,该对象具有将被执行的属性方法。检查对象以动态确定属性名称,我可以.toString()使用方法。

内部方法几乎肯定会包含异步调用,如下所示:

function doSomething(vars){
  var that = this,
      red = 'blue',
      up = 'down',
      one = 2;

   makeAsync(that,red,up,one,function(err,res){
      return makeDeep(res);
   }
}

如何从调用父方法中编组这些方法以最终返回值,而无需主动对文件 module1.js、module2.js 和 module3.js 进行可写访问。假设这些都是一成不变的,永远无法编辑。任何其他合理的东西都是公平的游戏。只是请不要说“好吧,重写 doSomething 以传入 CB 并让其makeDeep被包裹在 CB 中”。请注意,我是从我自己的代码中调用此模块,并注意这makeAsync是模块作者想要调用的任何异步方法。


重要说明:我是一个写makeDeep作者,我是一个包含模块的人,所以我可以在这两个地方做任何你想做的事情,并且makeDeep动态注入模块(我正在做一个混合模式)所以如果你的解决方案依赖于修改makeDeep工作或“父”调用方法中的某些东西,这是 100% 合理的,我就是这样。

如果是这种情况,则没有“需要”在return之前使用关键字,makeDeep但如果语法确实使用了这些词,则可以加分(这在很大程度上向开发人员表明这是一个代码出口点,是吗?)


假设 module1.js 看起来像:

module.exports = function() {
    this.doSomething11 = function doSomething(vars){
      var that = this,
          red = 'blue',
          up = 'down',
          one = 2;

       makeAsync(that,red,up,one,function(err,res){
          return makeDeep(res);
       }
    }
}

模块2.js

module.exports = function() {
    this.doSomething21 = function doSomething(vars){
      var that = this,
          red = 'blue',
          up = 'down',
          one = 2;

       makeAsync(that,red,up,one,function(err,res){
          return makeDeep(res);
       }
    };

    this.doSomething22 = function doSomething(vars){
      var that = this,
          red = 'blue',
          up = 'down',
          one = 2;

       makeAsync(that,red,up,one,function(err,res){
          return makeDeep(res);
       }
    };
}

模块3.js

module.exports = function() {
    this.doSomething31 = function doSomething(vars){
      var that = this,
          red = 'blue',
          up = 'down',
          one = 2;

       makeAsync(that,red,up,one,function(err,res){
          return makeDeep(res);
       }
    };

    this.doSomething32 = function doSomething(vars){
      var that = this,
          red = 'blue',
          up = 'down',
          one = 2;

       makeAsync(that,red,up,one,function(err,res){
          return makeDeep(res);
       }
    };

    this.doSomething33 = function doSomething(vars){
      var that = this,
          red = 'blue',
          up = 'down',
          one = 2;

       makeAsync(that,red,up,one,function(err,res){
          return makeDeep(res);
       }
    }
}

是的,这些例子是人为的,因为我更关注概念而不是实际细节。它们可以是三重嵌套的回调,或者可以使用某种内部回调。大多数情况下,我只是想知道是否有办法做到这一点。

如果没有,如果我为用户提供一个特定的库并让他们返回到库中,我怎样才能让它为用户工作?

我的目标是最终复制类似于 ASP.NET 样式 ActionResult 的东西,并且我对使用 Q、fiber 或 Promise 的想法持开放态度,但我在调用时遗漏了一些东西,以便在异步回调时将其取回用来。

4

1 回答 1

1

我会解决你的问题,它只需要调用所需的模块return that.makeDeep()而不是return makeDeep(). 我知道您不想更改被调用的代码,但是,您可以随时使用burrito并动态更改这些行(无需写入访问权限)。

调用代码

var Controller = require('./module1');
assert(typeof Controller == 'function');

httpServer.on('request', function(req, res) {
    // I assume this is something you would do
    var vars = processReqParameters(req);
    var action = vars.action;
    var controller = new Controller();

    if(typeof controller[action] === 'function') {
        // now I assume that makeDeep will at one point
        // call res.end();
        var makeDeep = createMakeDeep(req, res, vars) // or other parameters

        // this is how we inject makeDeep in the controller
        var controllerInstance = Object.create(controller, {makeDeep: makeDeep});
        return controllerInstance[action](vars);
    }
    else {
        res.writeHead(404, 'Controller Not Found');
        res.end('Too bad\n');
    }
})

调用代码

module.exports = function() {
    this.myAction = function(vars)  {
        var that = this,
            red = 'blue',
            up = 'down',
            one = 2;

        makeAsync(that, red, up, one, function(err, res) {
            return that.makeDeep(res);
        })
    }
}
于 2013-02-11T09:24:01.650 回答