Поведение опроса - PullRequest
0 голосов
/ 15 мая 2019

Я пишу эпос, который опрашивает сервер каждые определенное количество секунд, в данном случае 3-секундная задержка запуска, опрашивает каждые 5 секунд, используя таймер, передавая его по конвейеру, но я не уверен, что причина этого поведения,

Мои эпопеи не ждут, пока завершится моя внутренность, поэтому вывод действительно странный.

Я попытался изменить карту и использовать выхлопную карту, но не уверен, что я лаю нужное дерево.

export const testingEpics = action$ => {
  // Stop upon a end pending action trigger, for debugging/stopping if needed
  const stopPolling$ = action$.pipe(ofType(END_PENDING_ACTIONS));
  return action$.pipe(
    // On begin pending actions
    ofType(BEGIN_PENDING_ACTIONS),
    switchMap(action =>
      // At a 5 second interval
      timer(3 * 1000, 5 * 1000).pipe(
        // Stop when epics see a end pending action
        takeUntil(stopPolling$),
        switchMap(() =>
          // Get the db
          from(getDb()).pipe(
            mergeMap(db => {
              console.log('Run again!!');
              return from(
                new Promise(resolve => setTimeout(resolve, 10000))
              ).pipe(
                // what happens if action is still running but no internet?
                // delay(9.9 * 1000),
                // actions is an array from the db
                // switchmap at top is reason for it, handle for future. lol
                map(actions => console.log('Hello world'))
              );
            })
          )
        )
      )
    )
  );
};

Ожидаемый результат будет

(Initial delay 3 seconds) 
Run Again!!
(Wait's 10 seconds for inner promise to complete)
Hello world
(Subsequent delay of 5 seconds)
Run Again!!
(Wait's another 10 seconds for inner promise to complete)
Hello world
(Subsequent delay of 5 seconds)
Run Again!!
(Wait's another 10 seconds for inner promise to complete)
Hello world
(Subsequent delay of 5 seconds)
.
.
.

Ответы [ 2 ]

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

interval и timer могут использоваться для генерации цикла, который выполняется с частотой, не зависящей от времени, которое требуется для фактического опроса вашего сервера. Основываясь на описании «ожидаемого результата», похоже, что вы хотите частоту, на которую будет влиять период времени, необходимый для фактического опроса вашего сервера. Я думаю о вашем сценарии использования, как следующий (синхронный) цикл:

delay(3) // synchronously wait 3 seconds
while (!stopped) {
  pollServer() // synchronously poll server; may take N seconds
  delay(10) // synchronously wait 10 seconds
}

Я бы использовал repeatWhen, чтобы построить вышеупомянутый цикл в эпопее. repeatWhen облегчает запуск 10-секундной задержки только после завершения «итерации цикла». Вы просто задерживаете полное событие в наблюдаемых уведомлениях:

export const epic = action$ =>
  action$.pipe(
    ofType(BEGIN_PENDING_ACTIONS),
    exhaustMap(action => // ignore actions while the loop is already running
      of(action).pipe( // re-pipe so we can attach `takeUntil` to stop running the loop
        delay(3000), // this is the initial delay
        mergeMap(() =>
          from(getDb()).pipe( // this is the start of the loop iteration
            mergeMap(db => ...), // this is where you poll the server and emit Redux actions
            repeatWhen(complete$ =>
              complete$.pipe(
                delay(10000), // on complete, wait 10 seconds, then repeat!
              )
            ),
          )
        ),
        takeUntil(action$.pipe( // stop on end
          ofType(END_PENDING_ACTIONS)
        )),
      )
    ),
  )

Обратите внимание, что в приведенном выше примере repeatWhen просто повторно подпишется на from(getDb()). Значение db всегда будет кэшированным значением из первой итерации. Если вам нужно повторно выполнять getDb() на каждой итерации, тогда замените defer(() => from(getDb())).

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

Попробуйте изменить все switchMap на concatMap, если вы хотите, чтобы все запросы проходили и ставились в очередь, exhaustMap пропустит наблюдаемое излучение источника, пока не завершится внутреннее, так что вы можете пропустить много запросов. С другой стороны, switchMap отменит внутреннюю наблюдаемую, как только родительская наблюдаемая испустит, поэтому ваше getDb() обещание будет отменено

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