2010-11-16 12 views
6

Ho in una pagina HTML, un elemento che appare diverse volte e che esegue lo stesso JS. Il problema è che voglio fare una funzione specifica solo se è stata la prima a eseguirla (i suoi fratelli non l'hanno mai eseguita - ANCORA).Come creare un semaforo tra elementi HTML caricati asincroni

Ho bisogno di semaforo per la sincronizzazione tra di loro. Non riesco a sapere come dichiarare una variabile e fare semaforo in questo modo in JS.

risposta

7

Ci sono molti approcci.

È necessario mettere una bandiera da qualche parte. Nell'assenza di qualsiasi altra cosa, puoi metterlo su window, ma usare un nome che è improbabile che possa entrare in conflitto con qualcos'altro.

Poi il JavaScript è abbastanza semplice:

if (!window.myUniqueNameFlag) { 
    window.myUniqueNameFlag = true; 
    // Do your processing 
} 

Ma ancora una volta, mettere le cose sul window non è l'ideale se si può evitare, anche se è molto pratica comune. (Qualsiasi funzione o variabile dichiarata nell'ambito globale è una proprietà di window.)

Se la funzione è già dichiarata nell'ambito globale (e quindi già occupa un simbolo), è possibile farlo per evitare la creazione di un secondo simbolo. Invece di:

function foo() { 
    // ...your processing... 
} 

Fate questo:

var foo = (function() { 
    var flag = flase; 

    function foo() { 
     if (!flag) { 
      flag = true; 
      // ...your processing... 
     } 
    } 

    return foo; 
})(); 

Questo sembra complicato, ma in realtà non è: Definiamo una funzione anonima, all'interno del quale si definisce una variabile e una funzione annidata, allora torniamo al riferimento funzione nidificato e assegnarlo alla variabile esterna foo. Puoi chiamare lo foo e otterrai la funzione nidificata. La funzione nidificata ha un riferimento permanente alla variabile flag perché è un closure over the variable, ma nessun altro può vederlo. È completamente privato.

Una terza opzione è usare solo una bandiera sull'oggetto funzione stessa:

function foo() { 
    if (!foo.flag) { 
     foo.flag = true; 
     // ...do your processing... 
    } 
} 

funzioni sono solo gli oggetti con la possibilità di essere chiamati, in modo da poter aggiungere le proprietà a loro.

+2

Non è un'operazione atomica. teoricamente, entrambi gli elementi possono passare prima la condizione if, quindi assegnare la variabile – Himberjack

+5

@oshafran: JavaScript sui browser è garantito come thread a singolo thread escludendo l'uso dei nuovi [operatori Web] (http://www.w3.org/TR/workers /) roba, che richiede una sintassi esplicita. Quindi quanto sopra ** è ** atomico su un browser. Se stavi usando un altro ambiente e * se * quell'ambiente fosse multi-thread, dovresti usare i meccanismi di sincronizzazione forniti dall'ambiente. Ma hai detto questo basato su browser, quindi non sono necessari. –

+0

Grazie! .............. – Himberjack