Оператор Expand выполняется больше, чем ожидалось - PullRequest
2 голосов
/ 28 мая 2019

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

import { Observable } from 'rxjs';

const items = [
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    [11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
    [21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
];

const call = () => {
    console.log('#call');

    const batch = items.shift();

    if (batch) {
        return Observable.of(batch).delay(100);
    }

    return Observable.empty();
}

const o$ = call().expand((values) => {
    console.log('expansion');
    return call();
}).flatMap((val: any) => val);

const log = (prefix: string) => (...args: any[]) => console.log(prefix, ...args);

o$.take(9).subscribe(log('next'), log('error'), log('complete'));

Вывод отличается от того, что я хотел бы:

#call
takeWhile.ts:26 next 1
takeWhile.ts:26 next 2
takeWhile.ts:26 next 3
takeWhile.ts:26 next 4
takeWhile.ts:26 next 5
takeWhile.ts:26 next 6
takeWhile.ts:26 next 7
takeWhile.ts:26 next 8
takeWhile.ts:26 next 9
takeWhile.ts:26 complete
takeWhile.ts:22 expansion
takeWhile.ts:10 #call

Я получаю свои 9 элементов, что я и просил, используя take, затем поток завершается, но происходит одно дополнительное расширение, и mock async API снова вызывается.

Есть ли способ сделать мой код менее жадным и не начинать другую рекурсивную итерацию?

1 Ответ

0 голосов
/ 29 мая 2019

Ожидаемое поведение ожидается: expand вызывается раньше take, поэтому

  • мы получаем первое значение
  • развернуть выполняется, и выполняется вызов
  • , тогда все наблюдаемое немедленно отписывается от

. Поэтому необходимо сделать рекурсивный вызов асинхронным, чтобы take отписаться до этот звонок сделан.Самым простым исправлением кажется заменить return call(); на return timer(4).map(call); (или даже return defer(call);, который магическим образом работает: /).

См. Этот пример в действии

Так что, как правило, вам нужно сделать «паузу» / «пробел», чтобы ограничитель включился и отписался.

Надеюсь, это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...