5

モジュールがあります:

var progress = {
    val: 0
};

var service = (function(){

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

    return{
        someMethod: someMethod
    };

})();

export {service,progress}

someMethod配列が反復される操作を実行します。繰り返しごとに1つずつ増やしたいと思いprogress.valます。この進行状況は観察可能です。

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

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

残念ながら、オブザーバーのコールバックは 1 回だけ呼び出され、反復ごとに 1 つの項目を持つ変更の配列を保持します。

各反復でコールバックを呼び出すにはどうすればよいですか?

4

1 に答える 1

4

それが物体観察の仕組みです。

オブザーバーは、レコードのコレクションを使用して、クロックの次のティックでのみ起動します。個々の変更が行われたときに同期的に起動することはありません。Object.Observe 同期コールバックも参照してください。

目的を達成するための 1 つの方法は、イテレータを書き直して、ループのたびに「スリープ」し、Object.observe発火する機会を与えることです。必ずしもこの正確なアプローチを推奨しているわけではありませんが、例として:

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

これで、監視オブジェクトに対して行われたプロパティへの変更fnは、ループの反復中に報告されます。

promise を使用して同じことを達成できます。

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

たまたま async/await 環境にいる場合 (これは ES7 の機能ですが、Babel などのトランスパイラーで利用可能です)、次のこともできます。これは、内部では上記の promises アプローチとほぼ同等です。

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

余談ですが、ここでは IIFE は必要ありません。また、self宣言されていません。行で実行時エラーが発生することが予想されますself.progress = M.progress

于 2015-03-30T06:24:38.923 に答える