这需要2个史诗。
const ajaxCallerEpic = action$ => (
action$
.pipe(
ofType(AJAX_ACTION),
switchMap(({
payload,
payloadId,
}) => (
merge(
from(payload) // This is an array of items
.pipe(
mergeMap(() => (
timer(5000) // This is my AJAX call
.pipe(
switchMap(() => (
merge(
of(loadedAction),
of(
sentData(
payloadId
)
),
)
)),
)
)),
),
)
))
)
)
const ajaxResponsesEpic = action$ => (
action$
.pipe(
ofType(AJAX_ACTION),
switchMap(({
payload,
payloadId,
}) => (
action$
.pipe(
ofType(SENT_DATA_ACTION),
filter(({ id }) => (
id === payloadId
)),
bufferCount(
payload
.length
),
map(anotherAction),
)
))
)
)
重要的部分是第二部分SENT_DATA_ACTION
。我在调用它时传递了一个唯一的 ID,以确保您正在收听正确的 ID。如果您不发送所有这些,只要浏览器打开,它就会一直在监听。您始终可以在内部侦听器上添加超时以确保它完成。另一个问题是如果在运行 AJAX 调用之后ajaxResponsesEpic
设置action$
侦听器。ajaxCallerEpic
它很可能最终成为一个race
条件。为了解决这些问题,您需要先执行ajaxResponsesEpic
,以便设置动作侦听器,同时在其侦听后启动 AJAX 调用。
像这样:
const ajaxCallerEpic = action$ => (
action$
.pipe(
ofType(AJAX_READY_ACTION),
switchMap(({
payload,
payloadId,
}) => (
merge(
from(payload) // This is an array of items
.pipe(
mergeMap(() => (
timer(5000) // This is my AJAX call
.pipe(
switchMap(() => (
merge(
of(loadedAction),
of(
sentAjaxData(
payloadId
)
),
)
)),
)
)),
),
)
))
)
)
const ajaxResponsesEpic = action$ => (
action$
.pipe(
ofType(AJAX_ACTION),
switchMap(({
payload,
payloadId,
}) => (
merge(
(
action$
.pipe(
ofType(SENT_AJAX_DATA_ACTION),
filter(({ id }) => (
id === payloadId
)),
bufferCount(
payload
.length
),
map(anotherAction),
)
),
(
of(ajaxReadyAction)
),
)
))
)
)