2016-12-10 1 views
1

Я подписавшись на BehaviorSubjectroutes$, который излучает массив направленийНаблюдаемые итерация событие завершения

например ['left', 'top', 'left']

Затем я хочу регистрировать каждый элемент этого массива с задержкой в ​​200 мс, теперь после того, как весь элемент зарегистрирован, я хочу зарегистрировать route finished.

Я пробовал все события ()=>{} и finally() оператора, но оба они не срабатывают, так как routes$ все еще жив и может испускать новые направления.

/** Stream recent directions */ 
this.route$.switchMap(() => { 
    return Observable 
    .interval(200) 
    .timeInterval() 
    .take(this.route$.getValue().length) 
}).subscribe(
    (v) => { 
    if (v.value === this.route$.getValue().length) return; 
    let i = v.value; 
    this.moveStep(this.route$.getValue()[i]); 
    } 
); 

В настоящее время я использую этот метод обхода

.subscribe(
    (v) => { 
    if (v.value === this.route$.getValue().length) return; 
    let i = v.value; 
    this.moveStep(this.route$.getValue()[i]); 

    /** Check if it is the last iteration */ 
    if(i + 1 === this.route$.getValue().length){ 
     console.log('route finished'); 
     this.state = PlayerState.Idle; 
    } 
    } 
); 

Есть собственный способ для достижения этой цели в наблюдаемой?

+0

Не могли бы вы переписать это для ясности? – Asti

ответ

2

Если я правильно понял, что вы пытаетесь сделать, вы хотите испустить значение, когда массив, переданный в BehaviorSubject, был полностью повторен, и вы хотите получить только последнее значение.

Постарайтесь не использовать .getValue() непосредственно из цепи Observable, потому что содержимое .getValue() - это то, над чем вы должны работать в цепочке.

var routes$ = new BehaviorSubject(['default']); 

routes$.switchMap((arr) => { 
    return Observable.interval(200) 
     .take(arr.length) 
     .map(i => arr[i]) 
     .timeInterval() 
     .do(null, null,() => console.log('Complete')); 
}).subscribe(value => { 
    console.log(value); 
}); 

routes$.next(['left', 'top', 'left']); 

setTimeout(() => { 
    routes$.next(['top', 'right', 'down']); 
}, 1000); 

Это выводит на консоль:

TimeInterval { value: 'left', interval: 208 } 
TimeInterval { value: 'top', interval: 241 } 
TimeInterval { value: 'left', interval: 207 } 
Complete 
TimeInterval { value: 'top', interval: 204 } 
TimeInterval { value: 'right', interval: 200 } 
TimeInterval { value: 'down', interval: 205 } 
Complete 

Смотреть демо: https://jsbin.com/muxasa/5/edit?js,console

Обратите внимание, что ['default'] никогда не переизлучается потому switchMap() получает новый массив при вызове routes$.next(['left', 'top', 'left']);

+0

Я хочу регистрировать каждый элемент за 200 мс задерживать не только последний, но я хочу запустить действие, когда эти элементы регистрируются. (после этого итерации по массиву). ваш jsbin регистрирует только последнее значение –

+0

'.do', но теперь все элементы регистрируются сразу, могу ли я сохранить задержку в 200 мс между ними? –

+0

Спасибо, человек, я искал оператор 'do' –

0

Если ваш Наблюдаемый еще не завершен, но вы можете использовать debounce(), чтобы дождаться сертификата за какое-то время, прежде чем что-то делать. Другие варианты: buffer ваши значения по времени/количеству, а затем после того, как вы выбрали буфер, сделайте что-нибудь.