将数据注入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工作范围的范围