Задержка на основе элемента внутри коллекции

#rxjs #rxjs6

#rxjs #rxjs6

Вопрос:

я хочу отложить выделение из наблюдаемого на основе длительности элемента из внутреннего массива и распечатать это значение продолжительности; идентификатор в subscribe?

 [{id:1000},{id:2000},{id:3000},{id:4000}]
                  .map(x => of(x).pipe(delay( x.id)) )            
                     .subscribe(x=>{ console.log (x.id)});
  

Комментарии:

1. Вы также можете использовать delayWhen оператор для этого

2. @kos, не могли бы вы, пожалуйста, указать синтаксис в моем случае с delaywhen

3. ну, точно так же, как в примере, который я связал, просто: delayWhen(x => timer(x.id))

Ответ №1:

Я думаю, вы близки … если вы хотите проецировать каждое событие в новую наблюдаемую, тогда вам нужно использовать mergeMap вместо map .

 import { from, of } from 'rxjs'
import { delay, mergeMap } from 'rxjs/operators'

let events = [{id:1000}, {id:2000}, {id:3000}, {id:4000}]

from(events).pipe(
  mergeMap(event => of(event).pipe(
    delay(event.id),
  )),
).subscribe(event => { console.log(event.id) })
  

Но обратите внимание, что mergeMap каждое событие будет выполняться параллельно. Для вашего очень конкретного примера это означало бы, что каждое событие выводится с задержкой всего в 1 секунду между ними. Весь наблюдаемый объект завершится в общей сложности за 4 секунды.

Если вы хотите, чтобы задержка была временем между событиями, тогда вы хотели бы обрабатывать каждое последовательно. Вы могли concatMap бы посмотреть на это:

 import { from, of } from 'rxjs'
import { delay, mergeMap } from 'rxjs/operators'

let events = [{id:1000}, {id:2000}, {id:3000}, {id:4000}]

from(events).pipe(
  concatMap(event => of(event).pipe(
    delay(event.id),
  )),
).subscribe(event => { console.log(event.id) })
  

Опять же, для вашего очень конкретного примера, приведенное выше будет ждать на одну секунду дольше каждый раз между событиями. Это наблюдаемое завершится в общей сложности за 10 секунд.

Комментарии:

1. Вау, все ваши ответы такие подробные. Я читаю все ваши ответы и думаю, что наконец-то пойму rxjs ха-ха.

2. @Noitidart Ха-ха, спасибо. 😉 Я рад, что вы находите их полезными!

3. как я могу выполнить итерацию через родительский дочерний элемент, например {id:1, дочерний элемент:[{},{}]

4. @user6069595 Я бы рекомендовал задать новый вопрос, чтобы вы могли получить более подробный ответ. Часто бывает сложно передать код с помощью комментариев. Быстрым ответом было бы добавить что-то вроде .map(event => event.child) в начале процесса. Существует также вызываемый сокращенный оператор pluck , который делает это точно. Так что вы могли бы также добавить .pluck('child') в начале.