Cela fait deux jours que j'essaie de passer un tableau dans un rappel setTimeout.

J'ai regardé partout sur Internet et j'ai lu peut-être 10 questions différentes sur StackOverflow avec toutes leurs réponses. Je dois manquer quelque chose parce qu'après avoir essayé toutes ces choses différentes, cela ne fonctionne toujours pas. Voici ma position actuelle:

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

J'ai obtenu de toutes les différentes solutions que j'ai trouvé que ma méthode ici devrait fonctionner. Je fais clairement quelque chose de mal, car cela ne fonctionne pas.

Le problème est que, dans la fonction ias(), pixel_batch.length est égal à 3, ou cependant de nombreux éléments sont placés dans ce tableau, même dans la fonction testing(), pixels.length est la valeur correcte, mais à l'intérieur de la fonction RETOURNÉ par le test, pixels.length` est égal à 0 ...

A l'origine, c'est ce que j'avais essayé:

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

Comme je le pense, il n'est pas nécessaire de le faire via une fonction définie en externe, mais à ce stade, j'ai commencé à essayer quelque chose / tout.

Comment puis-je obtenir pixel_batch (le paramètre passé à ias()) dans le rappel de setTimeout?

[MODIFIER / METTRE À JOUR] Voici le code qui APPELLE réellement 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 MODIFIER / METTRE À JOUR 2]

J'aimerais pouvoir accepter toutes vos réponses, car vous aviez tous raison techniquement. C'est ma faute de ne pas vous avoir donné les bonnes informations pour commencer. J'ai voté pour tout le monde parce que vous méritiez tous la réponse, vous ne pouviez pas me la donner avec les informations fournies.

1
BumbleShrimp 7 déc. 2011 à 23:59

4 réponses

Meilleure réponse

Votre problème est ici:

ias(the_pixel_batch);
the_pixel_batch.length = 0;

Vous nettoyez le tableau avant l'exécution de setTimeout.


Tu devrais faire:

pixel_batch.length = 0;

... dans le rappel 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
RightSaidFred 7 déc. 2011 à 20:43

Modifiez-vous le pixel_batch tableau après l'appel ias() mais avant l'expiration du délai? Si oui, vous pouvez transmettre une copie du tableau:

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

(Notant que .slice () ne fait qu'un niveau unique copie complète du tableau ...)

1
nnnnnn 7 déc. 2011 à 20:34

Voici un bon article expliquant comment procéder: https://gullan.org.uk/ passage-paramètres-fonction-settimeout

Voici la conclusion: setTimeout(function(){myFunction(parameter)}, myTimeout);

2
jak.b 20 juil. 2018 à 17:54

Développant la réponse de David: Je pense que ce que vous voudrez peut-être quelque chose comme ceci:

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

Il n'y a pas besoin d'une fonction qui renvoie une fonction, vous pouvez simplement utiliser une fermeture pour appeler directement la fonction.

1
mattwigway 7 déc. 2011 à 20:15
8421710