我正在使用redux-observable来处理一个动作:
export const createPaymentMethod =
(getBraintreeToken: (Object) => Promise<*>, cardholderName: string) => ({
type: CREATE_PAYMENT_METHOD,
getBraintreeToken: () => getBraintreeToken({ cardholderName }),
});
const mapBraintreeError = err => Observable.of({
type: CREATE_PAYMENT_METHOD + FAILURE,
error: { response: err.message },
});
export const createPaymentMethodEpic = (action$: any, store: ReduxState) =>
action$.ofType(CREATE_PAYMENT_METHOD)
.switchMap(({ getBraintreeToken }) => Observable.fromPromise(getBraintreeToken()))
.switchMap(({ nonce }) =>
ajax(api.createPaymentMethod(store.billings.info.customer_id, nonce))
.mapSuccess(CREATE_PAYMENT_METHOD)
.mapFailure(CREATE_PAYMENT_METHOD),
)
.catch(mapBraintreeError);
我所做的是故意让getBraintreeToken()
承诺失败。这会导致epic执行catch
函数并返回CREATE_PAYMENT_METHOD + FAILURE
操作。这就是我的意图。
问题是当我第二次尝试打电话给史诗时。它没有执行......
修改 我已经转换了史诗,现在似乎工作了,但是,我仍然不明白为什么第一个例子被打破了(实际上我更喜欢第一部史诗的平面结构)。
export const createPaymentMethodEpic = (action$: any, store: ReduxState) =>
action$.ofType(CREATE_PAYMENT_METHOD)
.switchMap(({ getBraintreeToken }) =>
Observable.fromPromise(getBraintreeToken())
.switchMap(({ nonce }) =>
ajax(api.createPaymentMethod(store.billings.info.customer_id, nonce))
.mapSuccess(CREATE_PAYMENT_METHOD)
.mapFailure(CREATE_PAYMENT_METHOD),
)
.catch(mapBraintreeError),
);
答案 0 :(得分:1)
第一个版本的问题是error
通知到达switchMap
运算符,该运算符调用其错误逻辑导致链处理。
它必须是这样的,因为Observable会发出零或一个error
通知,但绝不会更多。
有关详细说明,请参阅The Observable Contract。
Observable可以制作零个或多个OnNext通知,每个通知代表一个发出的项目,然后它可以通过OnCompleted或OnError通知跟踪这些发射通知,但不能同时通过两者。 发出OnCompleted或OnError通知后,可能不再发出任何其他通知。
在代码的第二个版本中,您将catch
运算符置于switchMap
的回调中。此处也应用了一个error
通知规则,但是为每个值调用了回调,因此即使内部Observable发出错误,它也会被捕获(并转换为next
),然后被新的替换内部可观察。