Data:
- una sorta di app web basata su widget
- molte funzionalità JS
- alto accoppiamento (comunicazione / callback tra i widget) I widget
- si disegnano da soli
- alcuni widget devono eseguire un ridisegno completo e abbastanza costoso ogni volta che viene modificata una delle loro dipendenze.
Problema: ci possono essere catene di dipendenze complicate e diventa difficile assicurarsi che i cambiamenti si verifichino solo una volta per azione dell'utente.
Ad esempio:
-
A
deve essere ridisegnato seB
oC
cambia -
B
dipende dallo stato diC
- Quindi se
C
cambia, ancheB
e entrambi potrebbero finire col causare il routing diA
.
Se succede solo poche volte, è facile da risolvere. Ma quando succede dappertutto, diventa un incubo da ingegnere e rende la manutenzione ancora peggiore.
Suppongo che questo sia un problema un po 'comune, quindi deve esserci un metodo per trattare. Questo o i miei progetti sono imperfetti in qualche modo.
Qualche suggerimento? Sarebbe molto apprezzato uno schema di progettazione o un algoritmo per gestire i ridisegni limitanti.
Modifica
Bene, sulla base dei suggerimenti di Randall, ecco cosa sto pensando:
- Il semaforo è una variabile globale, ma senza elementi multi-threading, quindi in pratica solo un conteggio globale. Diamo un nome a questo
S
. Ne avrei uno per widget che richiede costosi ridisegni. -
S
ha un segnale e una funzione di attesa. Il segnale incrementaS
e aspetta lo decrementa. -
S
è inizializzato con una funzione di callback per l'estrazione del widget. - Ogni volta che viene attivato qualcosa (evento utente, ritorno ajax, ecc.) viene chiamato
S.signal()
. - Una volta che l'evento ha finito di cambiare le cose all'interno di un oggetto (dopo aver fatto callback), viene chiamato
S.wait()
. -
S.wait()
, dopo aver decrementatoS
controlla se il conteggio è 0. Se lo è, ridisegna.
Quindi se C
cambia:
-
C
esegueS.signal()
(S==1
) -
C
apporta le sue modifiche, callback aB
-
B
esegueS.signal()
(S==2
) -
B
apporta le sue modifiche -
B
esegueS.wait()
(S==1
, nessun ridisegno) -
B
finisce, C ricomincia. -
C
esegueS.wait()
(S==0
, ridisegna)
Come la bandiera sporca ma più di un conteggio sporco e penso che sia più facile da implementare. Può essere esteso per funzionalità aggiuntive abbastanza facile. Se, per qualche motivo, voglio ottimizzarlo in modo che non tutto venga ridisegnato in alcuni casi, posso aggiungere alcuni flag che rappresentano le cose da ridisegnare e ripristinarle ogni volta.
Inoltre, potrebbe essere sostituito con uno stack e fare praticamente la stessa cosa ma con alcune migliori capacità di estensione.
Modifica 2
La soluzione di Izkata si è rivelata di poco conto da implementare e solo leggermente meno flessibile. Sono necessarie solo 2 modifiche:
- Aggiungi una proprietà timerID al widget che deve essere ridisegnato.
- Avvolge la funzione di ridisegno in un timer:
Codice JS:
A.draw = function(){
var that = this;
clearTimeout(this.drawTimer);
this.drawTimer = setTimeout(function(){that._draw();},0);
}
A._draw = function(){
//old draw code goes here
//could be made "private" or nested in A.draw
}
- Non sono necessarie altre modifiche, quindi la tua interfaccia rimane la stessa e funziona a meno che non ti serva per lavorare con il codice Async come le chiamate ajax.