如何作为先前 ajax 调用的结果进行 ajax 调用,在 return 中应该分派多个操作
How to do an ajax call as a result for a previous ajax call which in return should dispatch multiple actions
我正在尝试在 rxjs 中实现一个场景,其中:
- 我对 api 进行了 ajax 调用以获取一些数据。
- 如果 jwt 令牌已过期,我会收到更新后的响应
代币
- 如果token已经更新,我需要重新执行之前的API
打电话
- 如果不是我return结果照常。
为此,我尝试在令牌更新后在 map() 中执行一个承诺,以重新执行初始 API 调用
每次它说:"Actions must be plain objects. Use custom middleware for async actions" –
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);
}));
我已经通过结合使用 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
})
);
我正在尝试在 rxjs 中实现一个场景,其中:
- 我对 api 进行了 ajax 调用以获取一些数据。
- 如果 jwt 令牌已过期,我会收到更新后的响应 代币
- 如果token已经更新,我需要重新执行之前的API 打电话
- 如果不是我return结果照常。
为此,我尝试在令牌更新后在 map() 中执行一个承诺,以重新执行初始 API 调用
每次它说:"Actions must be plain objects. Use custom middleware for async actions" –
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);
}));
我已经通过结合使用 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
})
);