2011-12-07 71 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()不僅使陣列...的一個層次的深層副本)