Наблюдение за свойствами модуля ES6

У меня есть модуль:

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);
           });
       });

К сожалению, обратный вызов наблюдателей вызывается только один раз, сохраняя массив изменений с одним элементом на итерацию.

Как я могу вызвать обратный вызов на каждой итерации?

1 ответ

Вот как работает наблюдение за объектом.

Наблюдатель будет стрелять только по следующему такту с набором записей. Он не срабатывает синхронно по отдельным изменениям по мере их внесения. Смотрите также Object.Observe Synchronous Callback.

Чтобы выполнить то, что вы хотите, один из подходов состоит в том, чтобы переписать ваш итератор так, чтобы он "спал" каждый раз через цикл, чтобы дать Object.observe шанс выстрелить. Я не обязательно рекомендую этот точный подход, но просто в качестве примера:

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

Теперь любые изменения в свойствах объекта наблюдения fn будет сообщено во время этой итерации цикла.

Вы можете сделать то же самое, используя обещания:

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 линия.

Другие вопросы по тегам