Неоднозначное наблюдаемое поведение RxJS для курсора Монго - PullRequest
0 голосов
/ 04 октября 2018

Я пытался написать некоторый код, превращающий монго-курсор в наблюдаемый.Я нашел много решений в Интернете, но я пытался создать мое с нуля, чтобы выучить RxJS.

Может кто-нибудь объяснить, почему следующий код дает вывод ниже?

export function cursor$ <T> (cursor: Cursor<T>): Observable<T> {

    let counter = 1

    const d$ = (): Observable<T> => {
        counter++
        return from(cursor.hasNext())
            .pipe(
                tap(() => console.log(counter, 'before')),
                concatMap(x => x ? from( <Promise<T>>cursor.next() ) : empty()),
                tap(() => console.log(counter, 'between')),
                expand(() => d$()),
                tap(() => console.log(counter, 'after'))
            )
    }

    return d$()
}

Каждый элемент регистрируется в подписке, и «готово» печатается по завершении.

2 'before'
2 'between'
2 'after'
{ _id: 5bb5d47bbfa2d3ea077c37a6, name: 'Jeff' }
3 'before'
3 'between'
3 'after'
3 'after'
{ _id: 5bb5d483bfa2d3ea077c37a8, name: 'Jerald' }
5 'before'
5 'before'
5 'between'
5 'after'
5 'after'
{ _id: 5bb5d493bfa2d3ea077c37aa, name: 'Somebody' }
7 'between'
7 'after'
7 'after'
7 'after'
{ _id: 5bb5df8dbfa2d3ea077c39c8, name: 'Waddup' }
10 'before'
10 'before'
10 'before'
10 'before'
10 'before'
done

1 Ответ

0 голосов
/ 04 октября 2018

Сортировка!

Проблема была в том, что я вызывал расширение в d$(), которое само вызывалось несколько раз.

Вот рабочий код с tap() s:

export function cursor$ <T> (cursor: Cursor<T>): Observable<T> {

    let counter = 0

    const next$ = () => from(cursor.hasNext())
        .pipe(
            tap(() => console.log(counter++, 'before')),
            concatMap(x => x ? from(<Promise<T>> cursor.next()) : empty()),
            tap(() => console.log(counter++, 'after')),
        )

    return next$().pipe(expand(() => next$()))
}

И желаемый вывод:

0 'before'
1 'after'
{ _id: 5bb5d47bbfa2d3ea077c37a6, name: 'Jeff' }
2 'before'
3 'after'
{ _id: 5bb5d483bfa2d3ea077c37a8, name: 'Jerald' }
4 'before'
5 'after'
{ _id: 5bb5d493bfa2d3ea077c37aa, name: 'Somebody' }
6 'before'
7 'after'
{ _id: 5bb5df8dbfa2d3ea077c39c8, name: 'Waddup' }
8 'before'
done
...