2015-03-23 14 views
5

Ho un modulo:proprietà Osservando ES6 modulo

var progress = { 
    val: 0 
}; 

var service = (function(){ 

    function someMethod(){ 
     progress.val++; 
    } 

    return{ 
     someMethod: someMethod 
    }; 

})(); 

export {service,progress} 

someMethod eseguirà un'operazione in cui viene iterato un array. Vorrei incrementare lo progress.val di uno ad ogni iterazione. Questo progresso dovrebbe quindi essere osservabile:

System.import('components/Service.js') 
    .then(function(M){ 
      self.progress = M.progress; 

      Object.observe(M.progress,function(c){ 
       console.dir(c); 
      }); 
     }); 

Sfortunatamente, l'osservatori callback viene richiamato solo una volta, in possesso di una serie di modifiche con un elemento per iterazione.

Come posso richiamare la richiamata su ogni iterazione?

+1

Questo in realtà non ha nulla a che fare con i moduli, quindi potresti voler pensare a cambiare il titolo della tua domanda. –

+0

se si desidera il comportamento di sincronizzazione, è possibile uccidere Object.observe e utilizzare invece getter/setter, qualcosa di meno vecchio stile ma simile a http://jsfiddle.net/g35orqrq/ – dandavis

risposta

3

Ecco come funziona l'osservazione degli oggetti.

L'osservatore scatterà solo al prossimo tick dell'orologio con una raccolta di record. Non si attiva in modo sincrono sulle singole modifiche man mano che vengono apportate. Vedi anche Object.Observe Synchronous Callback.

Per ottenere ciò che si desidera, un approccio consiste nel riscrivere l'iteratore in modo che "dorma" ogni volta attraverso il ciclo per dare a Object.observe la possibilità di sparare. Non sto necessariamente consigliare questo approccio preciso, ma solo come esempio:

function iterate(a, fn) { 
    (function loop() { 
     if (!a.length) return; 
     fn(a.shift()); 
     setTimeout(loop); 
    })(); 
} 

Ora, sarà segnalato eventuali modifiche alle proprietà apportate sull'oggetto osservare da fn durante tale iterazione del ciclo.

Si potrebbe realizzare la stessa cosa con le promesse:

function iterate(a, fn) { 
    a.reduce((p, e) => p.then(() => fn(e)), Promise.resolve()); 
} 

Se vi capita di essere in un/await ambiente asincrona (questa è una caratteristica ES7, ma disponibile in transpilers quali Babel), allora si potrebbe anche effettuare le seguenti operazioni, che sotto le coperte è circa equivalente alle promesse approccio di cui sopra:

async function iterate(a, fn) { 
    for (i of a) await fn(i); 
} 

per inciso, non avete bisogno di un IIFE qui. Inoltre, self non viene dichiarato: mi aspetto un errore di runtime sulla riga self.progress = M.progress.

+2

Non è attesa una funzionalità ES7? – Loupax

+1

Sì, ma ci sono strumenti che includono Babel (via rigeneratore) che lo trasporrà per voi. –

+2

Certo, credo solo che dovrebbe essere indicato poiché la domanda riguardava specificamente ES6 – Loupax