5

我有一个模块:

var progress = {
    val: 0
};

var service = (function(){

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

    return{
        someMethod: someMethod
    };

})();

export {service,progress}

someMethod将执行迭代数组的操作。我想progress.val在每次迭代时加一。然后应该可以观察到这一进展:

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

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

不幸的是,observers 回调只被调用一次,每次迭代都包含一个更改数组。

如何在每次迭代中调用回调?

4

1 回答 1

4

这就是对象观察的工作原理。

观察者只会在时钟的下一个滴答声中触发一组记录。它不会在进行单个更改时同步触发。另请参见Object.Observe 同步回调

为了完成您想要的,一种方法是重写您的迭代器,使其每次通过循环“休眠”以提供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 等编译器中可用),那么你也可以执行以下操作,这在幕后大致相当于上面的 Promise 方法:

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

顺便说一句,您在这里不需要 IIFE。另外,self没有声明——我预计会出现运行时错误self.progress = M.progress

于 2015-03-30T06:24:38.923 回答