将数据注入asynchronouscallback(使用node.js)

我正试图围绕如何使asynchronous编程工作。

在我目前的使用情况下,我有可能被调用的函数每秒多次,他们有callback,依靠多个variables之间可能会改变。

一个简单的例子:(为了简洁起见,使用coffeescript)

doSomething = (requestor, thing, action, callback) -> thing.takeAction action, (result) -> # actually a lot of times this nests down even further requestor.report result callback result 

如果在thing.takeAction返回其结果之前doSomething被多次调用不同的数据, 我认为我不能依赖于请求者和callback仍然是我需要它们的相同的东西。 正确?

为了避免这种情况,我需要以某种方式将请求者和callback注入takeAction的callback函数。 这有可能吗?

我有这样的想法

 doSomething = (requestor, thing, action, callback) -> thing.takeAction action, (result, _requestor = requestor, _callback = callback) -> _requestor.report result _callback result 

但是,这当然只是一个CoffeeScript的黑客,根本不工作。


顺便说一句,我正在尝试使用caolan / async模块来帮助我,但事实仍然是,我经常需要比asynchronous允许的更多的variables。 喜欢:

 doSomething = function(requestor, thing, action, callback) { // this might not need a waterfall, but imagine it would have nested further async.waterfall( [ function(next) { thing.takeAction(action, function(result) { // How can I know that action is still the same? next(null, result); }); }, function(result, next) { requestor.report(result); // requestor still the same? next(null, result); } ], function(err, result) { callback(result); // callback still the same? }); } 

它仍然让我面临同样的问题。 那我该怎么做呢?

感谢您的时间。

您需要将action对象内容与action值本身分开。 也就是说,内存中有一些对象,它在这个特定的上下文中被action名称引用。

例如,

 function test(action) { alert("Test1: " + action.value); setTimeout(function () { alert("Test2: " + action.value); }, 1000); } var action = { value: 1; }; test(action); action = { value: 2 }; alert("Action value outside: " + action.value); 

将提示“Test1:1”,“Action value outside:2”和“Test1:1”。 但是,一旦你replaceaction = { value: 2 };action.value = 2 ,最后一次警报将更改为“Test1:2”。

所以,如果你的问题是操作对象的某些字段被改变了,只要把它克隆在doSomething的第一行。 如果你的问题是对象的引用改变了,你不应该担心,它不会以任何方式影响你的doSomething

此外,随后对doSomething的调用不会“覆盖”callback中action参数的值,因为它是通过特定调用closures的:en.wikipedia.org/wiki/Closure_(computer_science)

例如,

 function test(action) { alert("Test1: " + action.value); setTimeout(function () { alert("Test2: " + action.value); }, 1000); } var action = { value: 1; }; test(action); action = { value: 2 }; test(action); 

Test1:1“,”Test1:2“,”Test2:1“和”Test2:2“(不是”Test1:1“,”Test1:2“,”Test2:2“和”Test2:2“因为你似乎害怕)。

我不确定使用CS是否真的有助于这个例子,让我把它与简单的JS:

 var doSomething = function (requestor, thing, action, callback) { thing.takeAction(action, function (result) { requestor.report(result); callback(result); }); }; // Following is completely safe: doSomething(r1, t1, a1, c1); doSomething(r2, t2, a2, c2); doSomething(r3, t3, a3, c3); 

每次调用doSomething时,都会创build新的函数范围。 所以在内部,创build并传递给takeAction的函数可以访问最初调用doSomething的参数(另一个doSomething调用不会改变!)。 这就是JavaScript工作范围的范围