我正在尝试在rxjs中实现以下方案:
为此,我正在尝试在令牌更新后在map()中执行promise,以重新执行初始API调用
每次都说:“动作必须是普通对象。对异步动作使用自定义中间件” –
const fetchEpic = (action$, store) =>
action$.pipe(filter(filterActions)).pipe(
mergeMap((actionParams) => {
const ajaxObservables = ajax(request).pipe(
takeUntil(action$.ofType(`${type}_CANCEL`, CANCEL_ALL_FETCH)),
map( ({ response: payload}) => {
if (payload.tokenUpdated) {
const promiseFetch = () => new Promise(resolve => {
ajax(request).pipe(map(({ response }) => resolve(response)));
});
return from(promiseFetch).pipe(
concatMap((result) => of(
{ type: SET_USER_TOKENS, payload },
{...onCompleteAction, payload: result, extraParameters}
)),
catchError(err => {
console.log(err)
})
);
}
else if (isJWTError(payload)) {
return ({ type: USER_LOGOUT })
} else {
return ({...onCompleteAction, payload, extraParameters});
}
}),
catchError(({ xhr: { response: payload }}) => {
const obsLogoutAction = (of({ type: USER_LOGOUT, error: true}));
const obsReturnAction = (of({ type, payload, error: true}));
if (isJWTError(payload)) {
return obsLogoutAction;
}
return obsReturnAction
})
);
let obs = [...loadingActionObservable, ajaxObservables ];
return concat(...obs);
}));
答案 0 :(得分:0)
我通过结合使用flatMap和concat解决了这个问题。
当令牌已更新并调度2个操作时,以下重复API调用:
ajax(request).pipe(flatMap(({ response }) => {
console.log('response', response);
return concat(
of({ type: SET_USER_TOKENS, payload }),
of({...onCompleteAction, payload: response, extraParameters})
);
}));
整个观察结果:
const ajaxObservables = ajax(request).pipe(
takeUntil(action$.ofType(`${type}_CANCEL`, CANCEL_ALL_FETCH)),
//map(({ response: payload }) => payload),
map(({ response: payload }) => {
console.log(payload);
if (payload.tokenUpdated) {
options.headers['x-xsrf-token'] = payload.csrfToken;
// first dispatch action to update user token
return ajax(request).pipe(flatMap(({ response }) => {
console.log('response', response);
return concat(
of({ type: SET_USER_TOKENS, payload }),
of({...onCompleteAction, payload: response, extraParameters})
);
}));
//return { type: SET_USER_TOKENS, payload };
// re-execute ajax request
}
else if (isJWTError(payload)) {
return of({ type: USER_LOGOUT })
} else {
return of({...onCompleteAction, payload, extraParameters});
}
}),
flatMap((res) => {
console.log(res);
return res;
}),
//repeatWhen(action$.ofType(SET_USER_TOKENS, SET_USER_TOKENS)),
catchError((error) => {
console.log(error);
const { xhr: { response: payload } = {} } = error;
const obsLogoutAction = (of({ type: USER_LOGOUT, error: true}));
const obsReturnAction = (of({ type, payload, error: true}));
if (payload && isJWTError(payload)) {
return obsLogoutAction;
}
return obsReturnAction
})
);