2017-02-19 13 views
0

Я пытаюсь создать эпик, который предпримет действие, а затем отправит два разных действия, а второй задержится на две секунды. После связки попыток, это было лучшим, что я мог сделать:Отправка замедленного второго действия с помощью Redux-Observable при сохранении первого

const succeedEpic = action$ => 
    action$.filter(action => action.type === 'FETCH_WILL_SUCCEED') 
    .mapTo({ type: 'FETCH_REQUEST' }) 
    .merge(Observable.of({ type: 'FETCH_SUCCESS' }).delay(2000)) 

К сожалению, кажется, что:

Observable.of({ type: 'FETCH_SUCCESS' }).delay(2000) 

Пробегает сразу после загружаемого мое приложения (а не когда событие приходит вниз родительский поток). Я заметил это, потому что действие FETCH_SUCCESS принимается редуктором ровно через две секунды после загрузки моего приложения. Я даже приложил console.log, чтобы подтвердить это:

const succeedEpic = action$ => 
    action$.filter(action => action.type === 'FETCH_WILL_SUCCEED') 
    .mapTo({ type: 'FETCH_REQUEST' }) 
    .merge(Observable.of({ type: 'FETCH_SUCCESS' }) 
      .do(() => console.log('this has begun')) 
      .delay(2000) 
     ) 

«это началось» записывается в консоль момент запускается приложение.

Я подозреваю, что это связано с тем, как Redux-Observable автоматически подписывается на вас.

Желаемое поведение является то, что я буду:

  1. Нажмите кнопку, которая отправляет FETCH_WILL_SUCCEED событие.
  2. Сразу же отправляется событие FETCH_REQUEST.
  3. Через две секунды отправлено событие FETCH_SUCCESS.

ответ

0

Может быть, более элегантное решение, но почему бы просто не использовать 2 эпоса и объединить их?

Первая отправляет выборку запроса:

const onFetchWillSucceed = action$ => action$.ofType('FETCH_WILL_SUCCEED') 
    .mapTo({ type: 'FETCH_REQUEST' }) 

Второй ждет 2 секунды и отправляет успех:

const onFetchRequest = action$ => action$.ofType('FETCH_REQUEST') 
    .delay(2000) 
    .mapTo({ type: 'FETCH_SUCCESS' }) 

И в конце концов, они просто объединяются в 1 эпическую

const both = combineEpics(onFetchWillSucceed, onFetchRequest) 
+0

Это не сработает, потому что мой следующий шаг - создать эпическую версию «fetch is fail», которая также отправляет FETCH_REQUEST, но последующее действие - FETCH_FAIL вместо FETCH_SUCCESS. – adrianmc

1

Получается, что мне нужно было обернуть оба моих события внутри mergeMap. Спасибо @dorus за канал RxJS Gitter за этот ответ.

Это мой рабочий результат:

const succeedEpic = action$ => 
    action$.filter(action => action.type === 'FETCH_WILL_SUCCEED') 
    .mergeMapTo(Observable.of({ type: 'FETCH_REQUEST' }) 
     .concat(Observable.of({ type: 'FETCH_SUCCESS' }) 
     .delay(1000))) 

merge должны работать, а вместо concat, но я думал, что concat делает лучше семантический смысл.