2015-03-23 10 views
5

Ich habe ein Modul:Observing ES6 Moduleigenschaften

var progress = { 
    val: 0 
}; 

var service = (function(){ 

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

    return{ 
     someMethod: someMethod 
    }; 

})(); 

export {service,progress} 

someMethod wird eine Operation durchzuführen, wo ein Array iteriert wird. Ich möchte progress.val um eins bei jeder Iteration erhöhen. Dieser Fortschritt soll dann zu beobachten sein:

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

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

Leider hat der Beobachter Rückruf nur einmal aufgerufen wird, eine Reihe von Änderungen mit einem Punkt pro Iteration zu halten.

Wie kann ich den Rückruf bei jeder Iteration aufrufen?

+1

Dies hat eigentlich nichts mit Modulen zu tun, deshalb sollten Sie vielleicht darüber nachdenken, den Titel Ihrer Frage zu ändern. –

+0

Wenn Sie das Synchronisierungsverhalten möchten, können Sie das Object.observe beenden und stattdessen einen Getter/Setter verwenden, etwas weniger altmodisch, aber ähnlich wie http://jsfiddle.net/g35orqrq/ – dandavis

Antwort

3

So funktioniert Objektbeobachtung.

Der Beobachter feuert nur auf den nächsten Tick der Uhr mit einer Sammlung von Datensätzen. Es feuert nicht synchron auf einzelne Änderungen, wie sie vorgenommen werden. Siehe auch Object.Observe Synchronous Callback.

Um zu erreichen, was Sie wollen, ist ein Ansatz, Ihren Iterator neu zu schreiben, so dass es jedes Mal durch die Schleife "schläft", um Object.observe eine Chance zu geben, zu schießen. Ich bin nicht unbedingt diesen präzisen Ansatz zu empfehlen, aber nur als Beispiel:

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

, nun alle Änderungen an Eigenschaften für das Objekt beobachtet gemacht durch fn werden während dieser Iteration der Schleife gemeldet werden.

Sie könnten das gleiche mit Versprechungen erreichen:

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

Wenn Sie in einer Asynchron/await Umgebung (in transpilers wie Babel ist dies ein ES7 Feature, aber verfügbar) sein passieren, dann könnte man auch folgendes tun, die unter der Decke über die äquivalent zu den Versprechungen ist oben nähern:

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

Als Nebenwirkung, Sie haben kein IIFE hier brauchen. Auch self ist nicht deklariert - ich erwarte einen Laufzeitfehler auf der self.progress = M.progress Zeile.

+2

Ist eine ES7-Funktion nicht zu erwarten? – Loupax

+1

Ja, aber es gibt Tools einschließlich Babel (über Regenerator), die es für Sie transpilieren wird. –

+2

Sicher, ich glaube nur, es sollte darauf hingewiesen werden, da die Frage speziell ES6 betraf – Loupax