有没有办法在 RxJS / Redux-observable 中连接非 Redux 操作?
Is there a way to concat non-Redux actions in RxJS / Redux-observable?
成功登录后,我试图在获取用户配置之前将令牌存储在本地存储中。目前我只是在 mergeMap
中存储令牌,然后在 return 语句中获取配置。但是,我很确定有一种方法可以使用 concat
或 concatMap
依次调用存储和提取函数。
const authEpic = action$ =>
action$.pipe(
ofType('auth/AUTHENTICATION_SUCCESS'),
mergeMap(action => {
const { jwt } = action.payload;
localStorage.setItem('token', jwt);
return of({
type: 'user/FETCH_CONFIG'
});
})
);
以下是我的一次尝试,但未成功。虽然在这种情况下可能有其他方法从组件内部处理存储和获取,但我想知道这种模式在我遇到的其他情况下应该如何工作。
const authEpic = action$ =>
action$.pipe(
ofType('auth/AUTHENTICATION_SUCCESS'),
mergeMap(action => {
const { jwt } = action.payload;
return concat(
localStorage.setItem('token', jwt),
of({ type: 'user/FETCH_CONFIG'})
);
})
);
也许你可以尝试使用 last()
运算符,Concat 将在序列中的每个项目完成时发出,这就是它不起作用的原因。
reuturn concat(
of(localStorage.setItem('token', jwt)),
of({ type: 'user/FETCH_CONFIG'})
).pipe(last());
我会采用你在问题中提到的第一种方法,因为 localStorage.setItem()
是同步的,因此在返回 FETCH_CONFIG
操作之前它总是被调用..
但是,如果您正在寻找替代方法,我建议您在返回 FETCH_CONFIG
操作之前使用 tap()
运算符分离逻辑。这也将确保按顺序调用这两个操作。
const authEpic = action$ =>
action$.pipe(
ofType('auth/AUTHENTICATION_SUCCESS'),
tap(({ payload: { jwt } }) => {
localStorage.setItem('token', jwt);
}),
mergeMap((action) => (of({
type: 'user/FETCH_CONFIG'
}))
);
但是,如果你真的想使用 concat()
,你需要将 localStorage.setItem()
动作包装在 of()
中以将其转换为可观察的,如 concat()
要求所有成员都是可观察的,并且需要等待第一个订阅(localStorage.setItem()
)完成,然后第二个订阅(FETCH_CONFIG
)才能开始。
const authEpic = action$ =>
action$.pipe(
ofType('auth/AUTHENTICATION_SUCCESS'),
mergeMap(action => {
const { jwt } = action.payload;
return concat(
of(localStorage.setItem('token', jwt)),
of({ type: 'user/FETCH_CONFIG'})
);
}),
);
concat
用于按照之前完成的顺序执行 observables。
检查来自 learnrx.io
的文档
You can think of concat like a line at an ATM, the next transaction (subscription) cannot start until the previous completes!
在您的示例中,我认为您不需要任何这些运算符,因为您没有在流程中执行任何异步操作。
您可以简单地使用以下代码更改您的代码:
action$.pipe(
ofType('auth/AUTHENTICATION_SUCCESS'),
tap(action => localStorage.setItem('token', action.payload)),
mapTo({ type: 'user/FETCH_CONFIG'})
);
成功登录后,我试图在获取用户配置之前将令牌存储在本地存储中。目前我只是在 mergeMap
中存储令牌,然后在 return 语句中获取配置。但是,我很确定有一种方法可以使用 concat
或 concatMap
依次调用存储和提取函数。
const authEpic = action$ =>
action$.pipe(
ofType('auth/AUTHENTICATION_SUCCESS'),
mergeMap(action => {
const { jwt } = action.payload;
localStorage.setItem('token', jwt);
return of({
type: 'user/FETCH_CONFIG'
});
})
);
以下是我的一次尝试,但未成功。虽然在这种情况下可能有其他方法从组件内部处理存储和获取,但我想知道这种模式在我遇到的其他情况下应该如何工作。
const authEpic = action$ =>
action$.pipe(
ofType('auth/AUTHENTICATION_SUCCESS'),
mergeMap(action => {
const { jwt } = action.payload;
return concat(
localStorage.setItem('token', jwt),
of({ type: 'user/FETCH_CONFIG'})
);
})
);
也许你可以尝试使用 last()
运算符,Concat 将在序列中的每个项目完成时发出,这就是它不起作用的原因。
reuturn concat(
of(localStorage.setItem('token', jwt)),
of({ type: 'user/FETCH_CONFIG'})
).pipe(last());
我会采用你在问题中提到的第一种方法,因为 localStorage.setItem()
是同步的,因此在返回 FETCH_CONFIG
操作之前它总是被调用..
但是,如果您正在寻找替代方法,我建议您在返回 FETCH_CONFIG
操作之前使用 tap()
运算符分离逻辑。这也将确保按顺序调用这两个操作。
const authEpic = action$ =>
action$.pipe(
ofType('auth/AUTHENTICATION_SUCCESS'),
tap(({ payload: { jwt } }) => {
localStorage.setItem('token', jwt);
}),
mergeMap((action) => (of({
type: 'user/FETCH_CONFIG'
}))
);
但是,如果你真的想使用 concat()
,你需要将 localStorage.setItem()
动作包装在 of()
中以将其转换为可观察的,如 concat()
要求所有成员都是可观察的,并且需要等待第一个订阅(localStorage.setItem()
)完成,然后第二个订阅(FETCH_CONFIG
)才能开始。
const authEpic = action$ =>
action$.pipe(
ofType('auth/AUTHENTICATION_SUCCESS'),
mergeMap(action => {
const { jwt } = action.payload;
return concat(
of(localStorage.setItem('token', jwt)),
of({ type: 'user/FETCH_CONFIG'})
);
}),
);
concat
用于按照之前完成的顺序执行 observables。
检查来自 learnrx.io
的文档You can think of concat like a line at an ATM, the next transaction (subscription) cannot start until the previous completes!
在您的示例中,我认为您不需要任何这些运算符,因为您没有在流程中执行任何异步操作。
您可以简单地使用以下代码更改您的代码:
action$.pipe(
ofType('auth/AUTHENTICATION_SUCCESS'),
tap(action => localStorage.setItem('token', action.payload)),
mapTo({ type: 'user/FETCH_CONFIG'})
);