我会明白:我有这个循环:
for (var i = 1; i <= toSchedule; i++) {
when = trackWrapper.lastPlay +
(trackDuration +
(looper.timeInterval - trackDuration));
track.play(true, when);
trackWrapper.lastPlay = when;
}
play
方法在体内有这个:
[...]
// Here when is a different value for each call (verified)
// Many calls of the play method are performed before the returned function below is run as a callback
function playingCallback(myWhen){
return function(buffers){
// Here myWhen will always be equal to the value of the last call occurred BEFORE the first callback execution
console.log("myWhen = "+myWhen);
[...]
};
};
var realCallback = playingCallback(when);
track.scheduled.push(when);
track.recorder.getBuffer(realCallback);
所以,例如:
play(true, 1);
play(true, 2);
play(true, 3);
// Wait for it...
myWhen = 3;
myWhen = 3;
myWhen = 3;
现在:我已经阅读了关于闭包的内容,我已经读过“臭名昭着的循环问题”,我在StackOverflow上已经阅读了数十个答案,但我无法弄清楚这一点。这是我第二次遇到回调问题,所以在这一点上,我想我还没有完全理解发生了什么。
请您解释一下上面的代码应该是什么问题?提前谢谢。
答案 0 :(得分:1)
通常,您应该了解以下规则:即使在退出范围之后,clousure也可以访问其“周围范围”。但它将是执行时范围的状态,而不是(!)在关闭的创建时间
如果在循环内创建闭包,它将可以访问循环变量。但循环很可能已经结束。所以循环变量将保持其最后一个循环的值。
因此,如果您的闭包是一个回调,您应该在创建时创建相关范围变量的副本,并在执行时使用此副本。您可以通过从立即执行的匿名函数
创建内部闭包来执行此操作(例如)function myOuterScope(count) {
for(i=0; i<count; i++) {
setTimeout((function(local_i) {
// this function will be immediately executed. local_i is a copy of i at creation time
return function() {
// this is the function that will be called as a callback to setTimeout
// use local_i here, and it will be 0, 1, 2 instead of 3, 3, 3
}
})(i)
, 1000);
}
}
myOuterScope(3);