У меня есть следующий эпос:
import {
map,
catchError,
switchMap,
takeUntil,
} from 'rxjs/operators';
import {
FETCH_JOKES,
jokesReceived,
FETCH_JOKES_CANCELLED,
jokesFetchFailed,
} from '../actions/jokes-action';
import { ofType } from 'redux-observable';
import { of, concat } from 'rxjs';
import { ajax } from 'rxjs/ajax';
const getJokes = () =>
ajax.getJSON('http://api.icndb.com/jokes/random?escape=javascript');
const fetchJokesEpic = action$ => {
return action$.pipe(
ofType(FETCH_JOKES),
switchMap(() =>
getJokes().pipe(
map(response => jokesReceived(response)),
catchError((err, act) => of(jokesFetchFailed(err))),
takeUntil(action$.pipe(ofType(FETCH_JOKES_CANCELLED)))
)
),
);
};
export default fetchJokesEpic;
всякий раз, когда отправляется FETCH_JOKES
, этот эпос начинает ajax
вызов и при успешном отправлении действия jokesReceived
или при неудаче jokesFetchFailed
.
Я хочу зациклить его, поэтому, если не будет отменено, конечная точка будет вызываться снова после завершения предыдущего вызова (успех или неудача).
Я думал, что мог бы использовать другой эпический тат, который будет реагировать на JOKES_RECEIVED
и FETCH_JOKES_ERROR
действия, а затем отправьте FETCH_JOKES
действие, которое должно снова запустить крик.
import { ofType } from 'redux-observable';
import {
delay,
map,
} from 'rxjs/operators';
import {
JOKES_RECEIVED,
FETCH_JOKES_CANCELLED,
FETCH_JOKES_ERROR,
fetchJokes,
} from '../actions/jokes-action';
const pollJokes = (action$, state$) => {
return action$.pipe(
ofType(JOKES_RECEIVED, FETCH_JOKES_ERROR, FETCH_JOKES_CANCELLED),
delay(2000),
map(action => {
console.log('pollJokes.map', action);
if(action.type === FETCH_JOKES_CANCELLED)
{
console.log("Cancelled")
return { type: 'POLL_STOPPED' };
}
else {
// loop
return fetchJokes();
}
})
);
};
export default pollJokes;
Однако это не работает, когда я отправляю действие FETCH_JOKES_CANCELLED
.Стек действий выглядит следующим образом:
@INIT
FETCH_JOKES
JOKES_RECEIVED
FETCH_JOKES
JOKES_RECEIVED
...
FETCH_JOKES_CANCELLED
FETCH_JOKES
JOKES_RECEIVED
POLL_STOPPED
FETCH_JOKES
JOKES_RECEIVED
...
Я пытался добавить takeUntil
к эпосу pollJokes
, но с такими же плохими результатами
const pollJokes = (action$, state$) => {
return action$.pipe(
ofType(JOKES_RECEIVED, FETCH_JOKES_ERROR, FETCH_JOKES_CANCELLED),
delay(2000),
map(action => {
console.log('pollJokes.map', action);
if(action.type === FETCH_JOKES_CANCELLED)
{
console.log("Cancelled")
return { type: 'POLL_STOPPED' };
}
else {
// loop
return fetchJokes();
}
}),
takeUntil(action$.pipe(ofType(FETCH_JOKES_CANCELLED)))
);
};
С этим apporachpollJokes
эпопея перестает работать, как только FETCH_JOKES_CANCELLED
отправляется в первый раз.Теперь я знаю, что эпопея завершена takeUntil
.
Что я могу сделать, чтобы эта "зацикленная" работа?Я мог бы догадаться, реализовать промежуточное программное обеспечение, которое на самом деле будет вызывать fetchJokes
при отправке JOKES_RECEIVED
, но я искал all-rxjs-решение,