2011-12-07 69 views
1

我一直在尝试两天来将数组传递给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的回调函数?

[编辑/ UPDATE] 下面是实际调用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编辑/ UPDATE 2]

我希望我能接受你的答案,因为你们在技术上都是对的。这是我的错,因为没有给你正确的信息开始。我向每个人投了票,因为你们都应该得到答案,你无法用所提供的信息给我。

+0

在一个非常快的第一眼,你的方法似乎听起来至少有 –

+0

我认为我们需要查看一些数据以便测试。我真的不明白你为什么要调用一个首先返回函数的函数。在'ias'中只有一个'setTimeout'被调用,所以回调可以独占访问该函数调用的变量值。 – RightSaidFred

+0

分解你的功能到它的基本部分,它似乎工作:http://jsfiddle.net/pxaXq/ – gilly3

回答

2

你的问题就在这里:

ias(the_pixel_batch); 
the_pixel_batch.length = 0; 

你的setTimeout运行前清除阵列。


你应该这样做:

pixel_batch.length = 0; 

...在setTimeout回调。

function ias(pixel_batch) { 
    ctx.fillStyle = "#000000"; 

    setTimeout(function() { 
     var color_to_draw, a, b, c, d, e, box, done, i; 

     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.length = 0; // <<--- RIGHT HERE 
    }, pixel_batch[0][4]); 
} 
+0

我认为它是bei ng复制到'ias()'函数内的varialbe'pixel_batch',这就是为什么我认为这不是问题。 – BumbleShrimp

+0

我不敢相信我曾经有过这个问题,现在我又有了。解决方法是在ias()的开始处执行'pixel_batch = pixel_batch.slice(0);'...... – BumbleShrimp

+0

@JonathonG:是的,要制作浅拷贝,需要'.slice() ',或者只是跳过切片,并在回调中清除数组。但是,它是一个指向传递给函数的相同数组的指针。 – RightSaidFred

2

这里的好文章,解释如何做到这一点:http://www.makemineatriple.com/2007/10/passing-parameters-to-a-function-called-with-settimeout

这里的结论是:setTimeout(function(){myFunction(parameter)}, myTimeout);

+0

我试过这个,无济于事。由于某种原因,当我尝试在回调函数内部访问数组时,传入的数组仍然有0长度 – BumbleShrimp

+2

我认为代码正在调用testing()返回的函数,所以直接在setTimeout()中调用测试(...)而不是封闭)是正确的。 – mattwigway

+1

您的匿名函数无法在参数上关闭 - setTimeout实际应用您的函数时,它的范围中没有定义的变量像素。大卫的回答总结了我的反应将会是什么,而没有进入其他解决方法的细节。 –

1

扩大大卫的回答:我觉得你可能想是这样的:

function draw() { 
     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(function() {draw(pixel_batch)},pixel_batch[0][4]); 
} 

不需要返回函数的函数,你可以直接使用闭包来调用函数。

+0

要么这样,要么关闭通过在函数中创建一个范围内的副本,这两个函数都可以工作 –

+0

然后它看起来像这个问题一定在别的地方,调用'ias(the_pixel_batch)'的函数重置'the_pixel_batch [ ]'拨到0的长度后 – BumbleShrimp

+0

是的,因为即使我的复制策略只是复制引用而不复制数组。 –

1

你修改pixel_batch阵列调用ias()之前之后的超时执行?如果是这样,你可以通过数组的副本:

setTimeout(testing(pixel_batch.slice(0)),pixel_batch[0][4]); 

(注意到.slice()不仅使阵列...的一个层次的深层副本)