在javascript

时间:2015-10-23 17:59:34

标签: javascript function asynchronous callback

我正在测试我的应用程序,我有一个依赖注入系统就像这样(我在这里粘贴一个非常简化的版本)

test.start = function(callback) {
  // do stuff;
  load(callback);
}
function load(callback) {
  var args = ...// read callback's arguments
  // args = ['moduleA', 'moduleB'];
  var injectedArgs = args.map(function(a) {
    return require('./lib/' + a);
  });
  // call function with deps injected
  callback.apply(null, injectedArgs);
}

// test.js
test.start(function(moduleA, moduleB) {
  moduleA.functionA();
  moduleB.functionB();
});

我需要做的是在调用回调并开始测试之前的异步作业,在这种特殊情况下,这将是

test.start = function(callback) {
  // do stuff;
  load(function(moduleA, moduleB, moduleC) {
    moduleC.resetData(function() {
      return callback(moduleA, moduleB);
    })
  });
}

我需要使这个动态,对于所有具有不同模块作为其回调参数的测试。 要求是

  • 我不想更改测试定义
  • 我必须每次测试只调用一次load

所以基本上我需要创建添加moduleC参数的中间函数,运行resetData函数并调用原始回调。

我可以使用构建动态扩展的参数列表 var fn = new Function(newArgumentList, /*function body*/)但我无法附加正确的函数体(使用字符串),因为我丢失了原始的回调上下文。

更新

DI库是modularity,它读取回调定义以获取依赖性。所以基本上,给定回调function(foo, bar) { ... }我需要创建一个新的function(foo, bar, db) { db.resetData(function() { return callback(foo, bar) } )}

2 个答案:

答案 0 :(得分:1)

如果load本身就是你可以改变的东西(例如,不是测试定义的一部分),你会很高兴知道这很容易做到:你使用{{1} }:

Function#apply

如果您可以更新 function load(callback) { var origCallback; if (/*flag saying you need to do this*/) { origCallback = callback; callback = function() { /*...do your injected work here...*/ return origCallback.apply(this, arguments); // `arguments` looks like pseudo-code, but it isn't; it's an identifier created in the function's scope (for non-arrow functions) }; } var args = ...// read callback's arguments // args = ['moduleA', 'moduleB']; var injectedArgs = args.map(function(a) { return require('./lib/' + a); }); // call function with deps injected callback.apply(null, injectedArgs); } 符号以使其指向新功能,您甚至可以更改load。< / p>

load

如果你很好奇,是的,你可以更新函数声明创建的符号(是的,每个规范的符号,而不是&#34;棘手&#34;)。例如,这是完全有效的:

var oldload = load;
load = function() {
    /*...do your reset work here...*/
    return oldload.apply(this, arguments);
};

示例:

&#13;
&#13;
function foo() {
    console.log("I'm foo");
}
var oldFoo = foo;
foo = function() {
    console.log("I'm the new foo");
    return oldFoo.apply(this, arguments);
};
foo(); // "I'm the new foo", then "I'm foo"
&#13;
function foo() {
  snippet.log("I'm foo");
}
var oldFoo = foo;
foo = function() {
  snippet.log("I'm the new foo");
  return oldFoo.apply(this, arguments);
};
foo(); // "I'm the new foo", then "I'm foo"
&#13;
&#13;
&#13;

答案 1 :(得分:0)

我最后找到了解决方案。 由于模块化支持类似角度的注入

['modules/a', 'modules/b', function(moduleA, moduleB) {
  // use modules here   
}]

我可以像这样编写自定义回调

var customCallback = function() {
  var args = Array.prototype.slice.call(arguments);
  var injectedDBModule = args.pop();
  injectedDBModule.resetData(function() {
    // call the original callback function
    return originalCallback.apply(null, args);
  }
}
var loadCallback = originalInjectedModules; // ['moduleA', 'moduleB']
loadCallback.push('db');
loadCallback.push(customCallback);
modularity.load(loadCallback);