将数组作为参数传递到 SetTimeout 回调中
我已经尝试了两天将数组传递到 setTimeout 回调中。
我一直在互联网上查找,并且阅读了大约 10 个不同的 StackOverflow 问题及其所有答案。我一定错过了一些东西,因为在尝试了所有这些不同的事情之后,它仍然不起作用。这就是我现在的立场:
function testing(pixels){
return function(){
for(i=0; i<pixels.length;i++){
a = pixels[i][0];
b = pixels[i][1];
c = pixels[i][2];
d = pixels[i][3];
box = pixels[i][5];
done = pixels[i][6];
color_to_draw = done ? box.color:active_color;
ctx.fillRect(a,b,c,d);
ctx2.clearRect(box.x-1,box.y-1,box.w,box.h);
draw_colored_box(box.x, box.y, box.w, box.h, color_to_draw, box.alpha, true, ctx2);
}
};
}
function ias(pixel_batch){
var color_to_draw;
ctx.fillStyle = "#000000";
var a, b, c, d, e, box, done, i;
setTimeout(testing(pixel_batch),pixel_batch[0][4]);
}
我已经摆脱了所有不同的解决方案,我发现我的方法应该有效。我显然做错了什么,因为它不起作用。
问题是,在函数 ias()
中,pixel_batch.length
等于 3,或者无论多少项都放入该数组中,即使在函数 中也是如此。 >testing()
, pixels.length
是正确的值,但是在通过测试返回的函数内部,pixels.length` 等于 0...
原来,这就是我所拥有的尝试过:
function ias(pixel_batch){
var color_to_draw;
ctx.fillStyle = "#000000";
var a, b, c, d, e, box, done, i;
setTimeout((function(pixels){
console.log(pixels.length);
return function(){
for(i=0; i<pixels.length;i++){
a = pixels[i][0];
b = pixels[i][1];
c = pixels[i][2];
d = pixels[i][3];
box = pixels[i][5];
done = pixels[i][6];
color_to_draw = done ? box.color:active_color;
ctx.fillRect(a,b,c,d);
ctx2.clearRect(box.x-1,box.y-1,box.w,box.h);
draw_colored_box(box.x, box.y, box.w, box.h, color_to_draw, box.alpha, true, ctx2);
}
};
})(pixel_batch),pixel_batch[0][4]);
}
相信不需要通过一个外部定义的函数,但此时我已经开始尝试任何事情。
如何将 Pixel_batch(传递给 ias() 的参数)放入 setTimeout 的回调中?
[编辑/更新] 下面是实际调用 ias()
的代码:
function redraw_boxes(){
//This loop simply draws the active boxes again, on top of the previous set.
//At this point in time there is no need to clear the canvas at all.
var i; var i2; var box;
var temp_pixelation_array = pixelation_array.slice(0);
var x_mod; var y_mod;
var random_array_key;
var max_runs;
var the_pixel_batch = [];
var num_pixels_per_batch = 3;
var speed_to_pixelate = 3;
var done;
var temptimer=0;
var timers = [];
for(i=0;i<newly_acquired_boxes.length;i++){
temptimer=0;
temp_pixelation_array = pixelation_array.slice(0);
max_runs = temp_pixelation_array.length;
box = boxes[newly_acquired_boxes[i].column][newly_acquired_boxes[i].row];
for(i2 = 0; i2<max_runs;i2++){
random_array_key = ~~((Math.random()*temp_pixelation_array.length));
x_mod = temp_pixelation_array[random_array_key][0];
y_mod = temp_pixelation_array[random_array_key][1];
temp_pixelation_array.splice(random_array_key,1);
done = i2<max_runs-1 ? true:true ;
the_pixel_batch.push([box.x+x_mod, box.y+y_mod, particle_size, particle_size,temptimer,box,done]);
if(the_pixel_batch.length>= num_pixels_per_batch){
ias(the_pixel_batch);
the_pixel_batch.length = 0;
temptimer += num_pixels_per_batch*speed_to_pixelate;
}
}
}
newly_acquired_boxes.length=0;
}
[2 EDIT/UPDATE 2]
我希望我能接受您所有的答案,因为您在技术上都是正确的。是我的错,一开始就没有给你正确的信息。我对每个人都投了赞成票,因为你们都应该得到答案,只是你们无法将所提供的信息交给我。
I've been trying for two days now to pass an array into a setTimeout callback.
I've been looking all over the internet, and I've read maybe 10 different StackOverflow questions with all their answers. I must be missing something because after trying all of these different things it still doesn't work. Here is where I stand right now:
function testing(pixels){
return function(){
for(i=0; i<pixels.length;i++){
a = pixels[i][0];
b = pixels[i][1];
c = pixels[i][2];
d = pixels[i][3];
box = pixels[i][5];
done = pixels[i][6];
color_to_draw = done ? box.color:active_color;
ctx.fillRect(a,b,c,d);
ctx2.clearRect(box.x-1,box.y-1,box.w,box.h);
draw_colored_box(box.x, box.y, box.w, box.h, color_to_draw, box.alpha, true, ctx2);
}
};
}
function ias(pixel_batch){
var color_to_draw;
ctx.fillStyle = "#000000";
var a, b, c, d, e, box, done, i;
setTimeout(testing(pixel_batch),pixel_batch[0][4]);
}
I've gotten out of all the different solutions I found that my method here should work. I am clearly doing something wrong, as it DOES NOT work.
The problem is that, in the function ias()
, pixel_batch.length
is equal to 3, or however many items get put into that array, even in the function testing()
, pixels.length
is the correct value, but inside the function RETURNED by testing, pixels.length` is equal to 0...
Originally, this is what I had tried:
function ias(pixel_batch){
var color_to_draw;
ctx.fillStyle = "#000000";
var a, b, c, d, e, box, done, i;
setTimeout((function(pixels){
console.log(pixels.length);
return function(){
for(i=0; i<pixels.length;i++){
a = pixels[i][0];
b = pixels[i][1];
c = pixels[i][2];
d = pixels[i][3];
box = pixels[i][5];
done = pixels[i][6];
color_to_draw = done ? box.color:active_color;
ctx.fillRect(a,b,c,d);
ctx2.clearRect(box.x-1,box.y-1,box.w,box.h);
draw_colored_box(box.x, box.y, box.w, box.h, color_to_draw, box.alpha, true, ctx2);
}
};
})(pixel_batch),pixel_batch[0][4]);
}
As believe it does not need to be done through an externally defined function, but at this point I've started trying anything/everything.
How can I get pixel_batch (the parameter passed to ias()
) into the callback for setTimeout?
[EDIT/UPDATE]
Here is the code that actually CALLS ias()
:
function redraw_boxes(){
//This loop simply draws the active boxes again, on top of the previous set.
//At this point in time there is no need to clear the canvas at all.
var i; var i2; var box;
var temp_pixelation_array = pixelation_array.slice(0);
var x_mod; var y_mod;
var random_array_key;
var max_runs;
var the_pixel_batch = [];
var num_pixels_per_batch = 3;
var speed_to_pixelate = 3;
var done;
var temptimer=0;
var timers = [];
for(i=0;i<newly_acquired_boxes.length;i++){
temptimer=0;
temp_pixelation_array = pixelation_array.slice(0);
max_runs = temp_pixelation_array.length;
box = boxes[newly_acquired_boxes[i].column][newly_acquired_boxes[i].row];
for(i2 = 0; i2<max_runs;i2++){
random_array_key = ~~((Math.random()*temp_pixelation_array.length));
x_mod = temp_pixelation_array[random_array_key][0];
y_mod = temp_pixelation_array[random_array_key][1];
temp_pixelation_array.splice(random_array_key,1);
done = i2<max_runs-1 ? true:true ;
the_pixel_batch.push([box.x+x_mod, box.y+y_mod, particle_size, particle_size,temptimer,box,done]);
if(the_pixel_batch.length>= num_pixels_per_batch){
ias(the_pixel_batch);
the_pixel_batch.length = 0;
temptimer += num_pixels_per_batch*speed_to_pixelate;
}
}
}
newly_acquired_boxes.length=0;
}
[2 EDIT/UPDATE 2]
I wish I could accept all your answers, as you were all technically right. It's my fault for not giving you the right information to begin with. I up voted everyone because you all deserved the answer, you just couldn't give it to me with the information provided.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您的问题就在这里:
您在
setTimeout
运行之前清除数组。您应该执行以下操作:
...在
setTimeout
回调中。Your problem is right here:
You're clearing the Array before the
setTimeout
runs.You should do:
...in the
setTimeout
callback.这里有一篇很好的文章解释了如何做到这一点: https://gullan.org.uk/ pass-parameters-function-settimeout
结论是:
setTimeout(function(){myFunction(parameter)}, myTimeout);
Here a good article explaining how to do this: https://gullan.org.uk/passing-parameters-function-settimeout
Here is the conclusion :
setTimeout(function(){myFunction(parameter)}, myTimeout);
扩展大卫的答案:我认为你可能想要的是这样的:
不需要返回函数的函数,你可以使用闭包直接调用函数。
Expanding on David's answer: I think what you may want is something like this:
There is no need for a function that returns a function, you can just use a closure to call the function directly.
您是否在调用
ias()
之后但在超时执行之前修改pixel_batch
数组?如果是这样,您可以传递数组的副本:(注意 .slice () 只对数组进行一级深拷贝...)
Are you modifying the
pixel_batch
array after callingias()
but before the timeout has executed? If so, you could pass a copy of the array:(Noting that .slice() only makes a one-level deep copy of the array...)