这是一个后续问题:How to suspend JavaScript to allow render
我编写了一个函数,它执行一种暂停的for循环(允许在其间进行渲染):
function loop(count, callback){
var counter = 0
var iteration = function(){
callback(counter)
counter ++;
if (counter < count){
setTimeout(iteration, 0)
}
}
iteration();
}
这很好用,例如loop(100, function(i){ console.log(i) } )
。并允许浏览器在每次迭代之间进行渲染。
然而,在循环之后执行之后的问题时会出现问题,因为无法保证循环已完成。实际上,我认为它有不的保证(因为主线程在第一次调用setTimeout之后继续)。嵌套这些循环时会加剧这种情况:
loop(10, function(i){
loop(10, function(j){
console.log(i + '-' + j)
})
})
/// This definitely does not output the numbers in order...
我的用例是我正在运行一些模拟,每个模拟包含许多步骤,我想在每个模拟之间进行渲染。我是以错误的方式来做这件事的吗?
答案 0 :(得分:2)
我将如何做到这一点:
编辑:阅读下面的OP评论后更新了答案:
function loop(count, callback, done) {
var counter = 0;
var next = function () {
setTimeout(iteration, 0);
};
var iteration = function () {
if (counter < count) {
callback(counter, next);
} else {
done && done();
}
counter++;
}
iteration();
}
loop(100, function (i, next) {
console.log(i);
next();
})
loop(10, function (i, nextI) {
loop(10, function (j, nextJ) {
console.log(i + '-' + j);
nextJ();
}, nextI);
});
输出:
1
1-1
2
1-2
3
1-3
4
1-4
5
1-5
6
1-6
7
1-7
8
1-8
9
1-9
10
11
2-1
<< ... >>
97
98
99
loop
函数可以有第三个参数done
,它将在循环完成后运行(如果存在)。回调将有第二个参数next
,当你想要运行下一次迭代时需要调用它。
这样,你可以在循环中调用异步函数,并让它按顺序运行。
答案 1 :(得分:0)
这似乎运作正常:
var log = function (i) { console.log(i) },
loop = function (count, callback) {
callback(count);
count--;
count > 0 && arguments.callee(count, callback);
}
loop(10, log);
console.log('end');
loop(5, log);