最近我发现JavaScript的requestAnimationFrame(回调)方法存在一个奇怪的问题。这是我的代码:
var callback = undefined;
for (var i = 0; i < 3; i++) {
var flag = 0;
callback = (function (index) {
return function () {
if (flag < 5) {
flag++;
console.log('K i=' + index + ' flag=' + flag);
window.requestAnimationFrame(callback);
}
}
})(i);
window.requestAnimationFrame(callback);
}
在我的预期中,应该在控制台中循环如下:
K i=0 flag=1
K i=0 flag=2
K i=0 flag=3
K i=0 flag=4
K i=0 flag=5
K i=1 flag=1
K i=1 flag=2
K i=1 flag=3
K i=1 flag=4
K i=1 flag=5
K i=2 flag=1
K i=2 flag=2
K i=2 flag=3
K i=2 flag=4
K i=2 flag=5
但事实上,控制台日志如下:
K i=0 flag=1
K i=1 flag=2
K i=2 flag=3
K i=2 flag=4
K i=2 flag=5
我应该怎么做才能使用for循环和requestAnimationFrame()来获得我的预期结果?
答案 0 :(得分:0)
window.requestAnimationFrame
是一个异步函数,对于i从0到2,你初始化三个外部window.requestAnimationFrame
任务;
在前三个外window.requestAnimationFrame
任务之后,i从0到2,并且标志增加到3;
目前,i为2,标志为3,每个内部if (flag < 5)
回调中都有一个if条件window.requestAnimationFrame
,因此内部回调只运行两次(对于flag = 4, flag = 5),i总是2。
我修改了代码:
for (var i = 0; i < 3; i++) {
(function (index) {
var flag = 0;
var callback = function () {
if (flag < 5) {
flag++;
console.log('K i=' + index + ' flag=' + flag);
window.requestAnimationFrame(callback);
}
}
window.requestAnimationFrame(callback);
})(i);
}
答案 1 :(得分:0)
为什么不使用ES6来让这项工作变得更容易:
for (let i = 0; i < 3; i++) {
for (let flag = 0; flag < 5; flag++) {
window.requestAnimationFrame(() => console.log('K i=' + i + ' flag=' + flag))
}
}
以上给出了预期的结果。
ES5解决方案
function loop1 (i) {
function loop2 (flag) {
window.requestAnimationFrame(function () {
return console.log('K i=' + i + ' flag=' + flag);
});
};
for (var flag = 0; flag < 5; flag++) {
loop2(flag);
}
};
for (var i = 0; i < 3; i++) {
loop1(i);
}