2015-03-23 10 views
5

У меня есть модуль:свойство 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

Это не имеет ничего общего с модулями, поэтому вы можете подумать об изменении названия вашего вопроса. –

+0

, если вы хотите синхронизировать поведение, вы можете убить Object.observe и вместо этого использовать геттер/сеттер, что-то менее старомодное, но похожее на http://jsfiddle.net/g35orqrq/ – dandavis

ответ

3

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

Наблюдатель будет стрелять только при следующем тике часов с коллекцией записей. Он не запускает синхронно по отдельным изменениям по мере их создания. См. Также 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, но доступно в transpilers, такие как Вавилонский), то вы могли бы также сделать следующее, что под одеялом о эквивалентна обещаниям подойти выше:

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

Как и в сторону, Вам не нужно IIFE здесь. Кроме того, self не объявлен - я ожидаю ошибку во время выполнения на линии self.progress = M.progress.

+2

Не ждет ли ES7 функции? – Loupax

+1

Да, но есть инструменты, в том числе Вавилон (через регенератор), который переведет его для вас. –

+2

Несомненно, я просто считаю, что это должно указывать на то, что вопрос был конкретно о ES6 – Loupax