Передача массива в качестве аргумента в обратный вызов SetTimeout - PullRequest
1 голос
/ 07 декабря 2011

Я уже два дня пытаюсь передать массив в обратный вызов 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 - правильное значение, но в функции, ВОЗВРАЩЕННОЙ при тестировании, pix.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?

[EDIT / 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 РЕДАКТИРОВАНИЕ / ОБНОВЛЕНИЕ 2]

Хотел бы я принять все ваши ответы, поскольку вы все были технически правы. Я виноват в том, что не дал вам правильную информацию для начала. Я проголосовал за всех, потому что вы все заслуживали ответа, вы просто не могли дать его мне с предоставленной информацией.

Ответы [ 4 ]

2 голосов
/ 08 декабря 2011

Ваша проблема прямо здесь:

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]);
}
2 голосов
/ 08 декабря 2011

Вот хорошая статья, объясняющая, как это сделать: https://gullan.org.uk/passing-parameters-function-settimeout

Вот вывод: setTimeout(function(){myFunction(parameter)}, myTimeout);

1 голос
/ 08 декабря 2011

Изменяете ли вы массив pixel_batch после , вызывая ias(), но до истечения времени ожидания?Если это так, вы можете передать копию массива:

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

(учитывая, что .slice () делает только одноуровневую копию массива ...)

1 голос
/ 08 декабря 2011

В продолжение ответа Дэвида: я думаю, что вы можете захотеть что-то вроде этого:

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]);
}

Нет необходимости в функции, которая возвращает функцию, вы можете просто использовать замыкание для непосредственного вызова функции.

...