【问题标题】:How to do an ajax call as a result for a previous ajax call which in return should dispatch multiple actions如何作为先前 ajax 调用的结果进行 ajax 调用,作为回报应该调度多个动作
【发布时间】:2019-11-21 04:17:58
【问题描述】:

我正在尝试在 rxjs 中实现一个场景:

  1. 我对 api 进行 ajax 调用以获取一些数据。
  2. 如果 jwt 令牌已过期,我会收到更新后的响应 令牌
  3. 如果token已经更新,需要重新执行之前的API 打电话
  4. 如果不是,我照常返回结果。

为此,我尝试在更新令牌时在 map() 中执行一个承诺,以重新执行初始 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);
}));

【问题讨论】:

    标签: rxjs6


    【解决方案1】:

    我已经通过使用 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
                            })
                        );
    

    【讨论】:

      猜你喜欢
      • 2011-08-31
      • 1970-01-01
      • 2014-10-01
      • 2017-03-31
      • 1970-01-01
      • 2014-08-13
      • 2019-11-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多