我正在使用Apollo-Client向我的GraphQL服务器发出查询和突变。由于Apollo有自己的错误处理,因此实现takeUntil函数来取消查询调用和我的突变要困难得多。
使用Apollo,这就是我的突变:
export const languageTimeZoneEpic = (action$) => {
return action$.ofType(CHANGE_LANGUAGE)
.mergeMap(action => client.mutate({
mutation: languageMutation,
variables: { id: action.id, language: action.selected_language }
}).then(result => changeLanguageFulfilled(result))
.catch(error => changeLanguageError(error))
);
};
我的突变没有问题,如果有错误,它会捕获它。
这里的问题是,如果我添加takeUntil()
函数,就像下面的例子中一样,我的函数就不再适用了。
export const languageTimeZoneEpic = (action$) => {
return action$.ofType(CHANGE_LANGUAGE)
.mergeMap(action => client.mutate({
mutation: languageMutation,
variables: { id: action.id, language: action.selected_language }
}).then(result => changeLanguageFulfilled(result))
.catch(error => changeLanguageError(error))
).takeUntil("END_LANGUAGE");
};
我想知道是否有办法能够使用takeUntil()
函数,即使我使用的客户端有自己的错误处理。
*如果我在变异完成之前发出另一个动作,那么将调用此处的takeUntil()。
谢谢
答案 0 :(得分:1)
takeUntil
不接受字符串作为其参数。相反,它期望它将订阅一个Observable,使用第一个next'd值作为信号。
redux-observable只有99.9%只是RxJS,所以所有运算符都不知道redux / actions 除之外的ofType
这是唯一的运算符redux-observable提供的 - 其余的是RxJS内置插件。
还存在隔离问题。如果您将takeUntil
放在mergeMap
的外部,您将取消整个Epic,而不仅仅是特定的apollo-client客户端。相反,我们需要将放在 mergeMap
内,因为我们正在处理Promise,所以我们需要使用Observable.from
来包装它。
export const languageTimeZoneEpic = (action$) => {
return action$.ofType(CHANGE_LANGUAGE)
.mergeMap(action =>
Observable.from(
client.mutate({
mutation: languageMutation,
variables: { id: action.id, language: action.selected_language }
})
.then(result => changeLanguageFulfilled(result))
.catch(error => changeLanguageError(error))
)
.takeUntil(action$.ofType('END_LANGUAGE'))
);
};
然而,使用Promise then
和catch
这样的说法可能不合适 - 如果您更喜欢使用Promises,我可能会建议不要使用redux-observable。当使用redux-observable时,如果我们没有其他选择(例如我们不控制apollo-client API),我们通常只能使用Promises。在这些情况下,我通常尽可能快地将它们包装为Observable,然后其余部分是正常的RxJS。
export const languageTimeZoneEpic = (action$) => {
return action$.ofType(CHANGE_LANGUAGE)
.mergeMap(action =>
Observable.from(client.mutate({
mutation: languageMutation,
variables: { id: action.id, language: action.selected_language }
}))
.map(result => changeLanguageFulfilled(result))
.catch(error => Observable.of(
changeLanguageError(error)
))
.takeUntil(action$.ofType('END_LANGUAGE'))
);
};
这有时意味着它更冗长,但主要是关于不使用Promise的catch
因为这会使你的代码在redux-observable中非常难以遵循。 “这是Promise catch还是Observable catch?”。当然,这只是我的观点:))
我认为apollo-client无法实际取消突变,因为真正的Promise不可取消。从技术上讲,这段代码只会忽略Promise的结果,而不是真正取消它(不可能)。