Come faccio a memorizzare le funzioni javascript in una coda affinché possano essere eseguite alla fine

Ho creato una class di coda in javascript e vorrei memorizzare le funzioni come dati in una coda. In questo modo posso accumulare richieste (chiamate di funzione) e rispondere ad esse quando ne ho bisogno (eseguendo effettivamente la funzione).

C’è un modo per memorizzare una funzione come dati, in qualche modo simile a

.setTimeout("doSomething()", 1000); 

tranne che sarebbe

 functionQueue.enqueue(doSomething()); 

Dove memorizzerebbe doSomething () come dati, quindi quando richiamo i dati dalla coda, la funzione verrebbe eseguita.

Sto indovinando che avrei dovuto fare Qualcosa () tra virgolette -> “doSomething ()” e alcuni come farlo chiamare la funzione utilizzando una stringa, qualcuno sa come si potrebbe fare?

Tutte le funzioni sono in realtà variabili, quindi in realtà è piuttosto semplice memorizzare tutte le funzioni nell’array (facendo riferimento a esse senza il simbolo () ):

 // Create your functions, in a variety of manners... // (The second method is preferable, but I show the first for reference.) function fun1() { alert("Message 1"); }; var fun2 = function() { alert("Message 2"); }; // Create an array and append your functions to them var funqueue = []; funqueue.push(fun1); funqueue.push(fun2); // Remove and execute the first function on the queue (funqueue.shift())(); 

Questo diventa un po ‘più complesso se si vogliono passare parametri alle proprie funzioni, ma una volta che si è configurato il framework per fare ciò una volta diventa facile ogni volta successiva. In sostanza, ciò che si intende fare è creare una funzione wrapper che, quando viene richiamata, triggers una funzione predefinita con un particolare contesto e set di parametri:

 // Function wrapping code. // fn - reference to function. // context - what you want "this" to be. // params - array of parameters to pass to function. var wrapFunction = function(fn, context, params) { return function() { fn.apply(context, params); }; } 

Ora che abbiamo una funzione di utilità per il wrapping, vediamo come viene utilizzato per creare future chiamate di funzioni:

 // Create my function to be wrapped var sayStuff = function(str) { alert(str); } // Wrap the function. Make sure that the params are an array. var fun1 = wrapFunction(sayStuff, this, ["Hello, world!"]); var fun2 = wrapFunction(sayStuff, this, ["Goodbye, cruel world!"]); // Create an array and append your functions to them var funqueue = []; funqueue.push(fun1); funqueue.push(fun2); // Remove and execute all items in the array while (funqueue.length > 0) { (funqueue.shift())(); } 

Questo codice potrebbe essere migliorato consentendo al wrapper di utilizzare una matrice o una serie di argomenti (ma farlo potrebbe confondere l’esempio che sto cercando di fare).

Risposta canonica pubblicata qui


Ecco una bella class di coda che puoi usare senza l’uso di timeout:

 var Queue = (function(){ function Queue() {}; Queue.prototype.running = false; Queue.prototype.queue = []; Queue.prototype.add_function = function(callback) { var _this = this; //add callback to the queue this.queue.push(function(){ var finished = callback(); if(typeof finished === "undefined" || finished) { // if callback returns `false`, then you have to // call `next` somewhere in the callback _this.next(); } }); if(!this.running) { // if nothing is running, then start the engines! this.next(); } return this; // for chaining fun! } Queue.prototype.next = function(){ this.running = false; //get the first element off the queue var shift = this.queue.shift(); if(shift) { this.running = true; shift(); } } return Queue; })(); 

Può essere usato in questo modo:

 var queue = new Queue; queue.add_function(function(){ //start running something }); queue.add_function(function(){ //start running something 2 }); queue.add_function(function(){ //start running something 3 }); 

Fare riferimento alla funzione che si sta memorizzando senza () alla fine. doSomething è una variabile (che sembra essere una funzione); doSomething() è un’istruzione per eseguire la funzione.

In seguito, quando si utilizza la coda, si vorrà qualcosa come (functionQueue.pop())() – cioè, eseguire functionQueue.pop, e quindi eseguire il valore di ritorno di tale chiamata per pop.

Puoi anche usare il metodo .call () di un object funzione.

 function doSomething() { alert('doSomething'); } var funcs = new Array(); funcs['doSomething'] = doSomething; funcs['doSomething'].call(); 

Inoltre, puoi anche aggiungere la funzione direttamente alla coda:

 funcs['somethingElse'] = function() { alert('somethingElse'); }; funcs['somethingElse'].call();