观察ES6模块属性

时间:2015-03-23 09:57:56

标签: javascript observer-pattern ecmascript-6 object.observe

我有一个模块:

var progress = {
    val: 0
};

var service = (function(){

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

    return{
        someMethod: someMethod
    };

})();

export {service,progress}

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

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

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

不幸的是,观察者回调只被调用一次,每次迭代都有一个项目的变化数组。

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

1 个答案:

答案 0 :(得分:3)

这就是对象观察的工作方式。

观察者只会使用一组记录在<时钟的下一个时钟>处激活。它不会在个别更改时同步触发。另请参阅Object.Observe Synchronous Callback

为了实现你想要的,一种方法是重写你的迭代器,使它每次通过循环“休眠”,给Object.observe一个机会射击。我不一定推荐这种精确的方法,但仅作为一个例子:

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

现在,在循环的迭代过程中,将报告fn对观察对象所做的属性的任何更改。

你可以使用promises完成同样的事情:

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

如果您碰巧处于异步/等待环境中(这是ES7功能,但在Babel等转发器中可用),那么您还可以执行以下操作,这些内容与上面的承诺方法大致相同:

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

顺便说一句,你在这里不需要IIFE。此外,未声明self - 我预计self.progress = M.progress行上会出现运行时错误。