我有一个函数my_fn
,它可以更改某些元素的数据并进行转换。
我想在for循环中调用该函数,以便一次进行一次更改和过渡,并在它们之间短暂停留。
以下代码段可能无法单独运行,但显示了问题:
function updateData(){
for (i=0; i<20; i++){
my_fn();
//console.log('sleeping...');
//sleep(300);
}
}
function my_fn(){
var delay_amount = 300;
focus.selectAll('circle')
.transition()
.delay(delay_amount)
.attr('cy', function(d, i){
if (d.index == 5){
d.y += change_amount;
}
return y(d.y);
});
}
我正在尝试使用d3的delay()
函数进行过渡。但是,当我运行此命令时,它会暂停(延迟量),然后所有圆都立即移动。由此看来,my_fn
会立即被调用20次,所有过渡都被延迟,然后它们都立即发生。
为解决此问题,我尝试在updateData()
中添加注释的代码(具有仅在while循环中等待的睡眠功能)。这似乎要等待300毫秒的睡眠周期中的20个,然后立即进行所有转换。
这是怎么回事?我该如何实现?
NB:我见过this question,并且似乎在问类似的问题,但是答案似乎不起作用。我相信这是因为尽管不确定,但从selectAll
调用了它们的“循环”。
答案 0 :(得分:3)
您说对my_fn()
的立即呼叫是正确的。 delay()
调用对for循环没有影响,因此对my_fn()
的所有20个调用都将立即调度。
要获得所需的效果,您必须使用回调,以便在上一个操作完成之前才进行对my_fn()
的下一个调用。您可以像这样用d3做到这一点
function my_fn(){
var delay_amount = 300;
focus.selectAll('circle')
.transition()
.delay(delay_amount)
.attr('cy', function(d, i){
if (d.index == 5){
d.y += change_amount;
}
return y(d.y);
})
.on('end', my_fn);
}
或者,如果您真的想使用for循环,则可以像下面这样使用setTimeout:
function updateData(){
for (i=0; i<20; i++){
setTimeout(my_fn, 300 * i);
}
}
编辑:
请注意,第一个示例将永远递归调用my_fn()
,因此您需要实现某种逻辑以在第二十次调用之后停止。