#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')
в начале.