简体   繁体   English

观察ES6模块属性

[英]Observing ES6 Module properties

I have a module: 我有一个模块:

var progress = {
    val: 0
};

var service = (function(){

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

    return{
        someMethod: someMethod
    };

})();

export {service,progress}

someMethod will perform an operation where an array is iterated. someMethod将执行迭代数组的操作。 I would like to increment progress.val by one at each iteration. 我想在每次迭代时将progress.val递增一。 This progress should then be observable: 然后应该观察到这一进展:

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

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

Unfortunately, the observers callback is invoked only once, holding an array of changes with one item per iteration. 不幸的是,观察者回调只被调用一次,每次迭代持有一个项目的变化数组。

How can I invoke the callback on each iteration? 如何在每次迭代时调用回调?

That's how object observing works. 这就是对象观察的工作原理。

The observer will only fire at the next tick of the clock with a collection of records. 观察者只会在时钟的下一个刻度处用一组记录开火。 It does not fire synchronously on individual changes as they are made. 它不会在个别更改时同步触发。 See also Object.Observe Synchronous Callback . 另请参见Object.Observe Synchronous Callback

To accomplish what you want, one approach is to rewrite your iterator so that it "sleeps" each time through the loop to give Object.observe a chance to fire. 为了实现你想要的,一种方法是重写你的迭代器,以便它每次通过循环“休眠”,给Object.observe一个机会射击。 I'm not necessarily recommending this precise approach, but just as an example: 我不一定推荐这种精确的方法,但仅作为一个例子:

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

Now, any changes to properties made on the observe object by fn will be reported during that iteration of the loop. 现在,将在循环的迭代期间报告由fn对observe对象进行的属性的任何更改。

You could accomplish the same thing using promises: 你可以使用promises完成同样的事情:

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

If you happen to be in an async/await environment (this is an ES7 feature, but available in transpilers such as Babel), then you could also do the following, which under the covers is about equivalent to the promises approach above: 如果您恰好位于异步/等待环境中(这是一个ES7功能,但在Babel等转换器中可用),那么您还可以执行以下操作,这些内容与上面的promises方法大致相同:

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

As an aside, You don't need an IIFE here. 顺便说一句,你不需要这里的IIFE。 Also, self is not declared--I expect a run-time error on the self.progress = M.progress line. 此外,未声明self - 我期望self.progress = M.progress行上出现运行时错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM