2009-09-20 18 views
6

Sto scrivendo un plugin di ubiquity, la callback di funzione lunga per una query ajax sta bloccando il thread GUI che causa il blocco di firefox.Esiste un modo corretto di "rendimento" nel senso del threading cooperativo in javascript?

La soluzione più ovvia sembra essere quello di utilizzare una sorta di esecuzione differita di (vale a dire che vogliamo aggiungere periodicamente il portano fuori facendo questa query funzione per la fine della coda degli eventi e quindi consentire altri comandi da eseguire .

L'unico modo che posso pensare di fare questo è quello di utilizzare setTimeout con un timeout pari a zero ... questo è è garantito per funzionare, o c'è un modo migliore di fare questo.

+0

Come stai facendo l'AJAX? Se stai caricando un tag script, questo potrebbe bloccarsi (i blocchi del browser finchè lo script non ritorna). –

+0

Sto usando jQuery.get – user47741

risposta

7

Utilizzando setTimeout con un timeout molto piccolo (0 o quasi zero se ti senti paranoico) è l'unico modo per farlo in un contesto di browser. funziona molto bene ed è molto affidabile, ma assicuratevi di produrre abbastanza spesso ma non troppo spesso, poiché ci vuole un po 'per tornare da voi ("un po'" in senso computer, ovviamente; è quasi istantaneo [modulo altre cose che potresti fare] in termini umani).

+2

Tutte le moderne implementazioni del browser hanno impostato setTimeout a ~ 10ms (in pratica 10ms su tutti i sistemi non Windows, in cui la risoluzione del timer richiesta per ottenere timer <16ms ha un impatto significativo sull'utilizzo di energia). Quindi non devi davvero preoccuparti di interrompere un timeout. – olliej

+1

@olliej: informazioni obsolete (se era corretto nel '09, ma non era nemmeno la mia esperienza). I browser hanno una gestione molto più sofisticata di quella, a seconda dell'origine della chiamata 'setTimeout'. Questo è stato [codificato un paio di anni fa nelle specifiche HTML5] (http://www.w3.org/TR/html5/webappapis.html#timer-initialization-steps) ma, come ho detto, i venditori stavano già giocando (disparati) i giochi prima di allora. Versione breve: se il tuo codice non è stato chiamato da un timer, puoi usare 0, e i browser moderni avranno ** molto ** vicino a quello. –

3

Assicurarsi che si stia utilizzando una richiesta asincrona poiché una richiesta sincrona blocca il browser (che spiegherebbe il blocco della GUI).

Se questo non è un problema, penso che vogliate qualcosa come questa coda di attività.

var queue = []; 

queue.push(someTaskFunction); 
queue.push(anotherTaskFunction); 
// ... 

var runQueue = (function() { 
    var len = queue.length, task = 0; 
    for (; task < len; task++) { 
     yield queue[task](); 
    } 
}()); 

Chiamare runQueue.next() per eseguire l'attività successiva. Avvolgilo in una dichiarazione try..catch in quanto tale:

try { 
    runQueue.next(); 
} catch (e if (e instanceof StopIteration)) {} 
+0

La chiamata è asimmetrica – user47741

+0

Fresco - Non ero a conoscenza del fatto che i generatori fossero stati aggiunti a javascript. Ho ragione nel capire che altre attività possono assumere un controllo ogni volta che viene restituita una funzione? – user47741

+0

Si noti che i generatori sono relativamente nuovi in ​​JavaScript e non necessariamente ampiamente supportati. –