作为上一个ajax调用的结果,如何进行ajax调用,作为回报,该ajax调用应分派多个动作

时间:2019-11-20 15:59:41

标签: rxjs6

我正在尝试在rxjs中实现以下方案:

  1. 我对API进行了ajax调用以获取一些数据。
  2. 如果jwt令牌已过期,我将收到更新的响应 令牌
  3. 如果令牌已更新,则需要重新执行以前的API 致电
  4. 如果没有,我照常返回结果。

为此,我正在尝试在令牌更新后在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);
}));

1 个答案:

答案 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
                        })
                    );