rxjs - Redux Observable - 如何发送一个动作来开始一个单独的史诗,然后等待史诗响应(或超时)
问题描述
所以我基本上有一个websocket 连接,这允许我通过 WEBSOCKET_MESSAGE_SEND 发送通用消息并通过 WEBSOCKET_MESSAGE_RECEIVED 操作接收它们。
但是,在某些情况下,我想以与 Ajax REST 调用类似的方式发出请求。例如,为用户请求文档列表,我可能想要一个史诗:
- 接收一个动作,例如
({ type: GET_DOCUMENTS })
- 生成一个随机密钥来跟踪当前的请求,我们称之为
'request_id'
- 发送
({ type: WEBSOCKET_MESSAGE_SEND, request_id })
动作。 - 等待任何一个
- 一个动作
({ type: WEBSOCKET_MESSAGE_RECEIVED, request_id, message })
**必须有一个匹配的“request_id”,否则它应该被忽略。- -> 发出一个动作,例如
({ type: GET_DOCUMENTS_SUCCESS, documents: message })
- -> 发出一个动作,例如
- 超时,例如 10 秒
- -> 发出一个动作,例如
({ type: GET_DOCUMENTS_TIMEOUT })
- -> 发出一个动作,例如
- 一个动作
我一直在努力将其放入代码中,我认为整个史诗中最尴尬的部分是我想在史诗中间发出一个动作并等待。这对我来说感觉不太对劲……ani-pattern?但我不确定我应该怎么做。
解决方案
这是正确的。没有什么好的方法可以在史诗的中间发出一个动作。把史诗分成两部分怎么样?
const getDocumentsEpic = action$ =>
action$.pipe(
ofType("GET_DOCUMENTS"),
map(() => {
const requestId = generateRequestId();
return {
type: "WEBSOCKET_MESSAGE_SEND",
requestId
};
})
);
const websocketMessageEpic = action$ =>
action$.pipe(
ofType("WEBSOCKET_MESSAGE_SEND"),
switchMap(requestId => {
return action$.pipe(
ofType("WEBSOCKET_MESSAGE_RECEIVED"),
filter(action => action.requestId === requestId),
timeout(10000),
map(({ message }) => ({
type: "GET_DOCUMENTS_SUCCESS",
documents: message
})),
catchError(() => of({ type: "GET_DOCUMENTS_TIMEOUT" }))
);
})
);
推荐阅读
- excel - 通过 VBA 从 Access 导入特定的 Excel 工作表
- arrays - Angular 5 - 从 FormGroup 创建对象数组将相同的对象推送到我的数组中
- python - 使用递归时返回无的函数
- javascript - S3 JS SDK copyObject 403 禁止
- excel - 句子标点返回 True-Spacy
- java - CompletableFuture with Runnable-delegation - 在委托类中忽略异常
- ruby-on-rails-5 - 嵌套设计用户的显示路径助手
- sql - 从组中选择最近的日期
- javascript - 网站启动时立即运行 iframe
- html - 为什么当我使用 svg 线时,我的 div 附近会出现一个未识别的段?