数据不是从史诗到减速器

时间:2017-12-01 10:48:50

标签: reactjs redux rxjs redux-observable

如果你们中的任何人都看到了这个问题,那么我对redux是一个新问题,而且我来自角度和服务逻辑,所以我知道redux是如何工作的。我只使用了2个史诗监听器(一个用于从服务调用GET方法,一个用于POST)+服务(用于从api获取数据)。因此,每当我打电话给任何api我做一个api配置的对象,包括url,param,如果在api中包含授权头,那么当我一次发出一个动作但是当我和#39;做多个动作意味着多次获取或发布它在完成所有服务和史诗工作后停止在史诗中,并且没有去减速器存储数据并给我错误。 Actions must be plain objects. Use custom middleware for async actions 我知道我的实施中出现了问题。如果它以这种方式工作,那将是非常好的,我将转移到thunk等其他服务。

 `
GetEpic = (action$) =>
            action$.ofType(Action.Get)
                .switchMap(({ payload }) => {
                    let { api, param, reqHeader, waitFor } = payload;
                    delete payload.api;
                    delete payload.param;
                    delete payload.reqHeader;
                    return HttpService.post(api, param, reqHeader, payload).then((userInfo) => {
                        if (userInfo.status && userInfo.status != 200) {
                            return {
                                type: 'ERROR'
                            }
                        }
                        return this.translateDataAndReturnType(userInfo, api, 'get', waitFor);
                    }).catch(() => {
                        return {
                            type: 'ERROR'
                        }
                    })
                })

translateDataAndReturnType(data, api, method, waitFor) {
        if (data && api) {
            this.count += 1;
            let actionInfo = this.routesData.find((d, i) => {
                return d.route == api
            })
            let routeAction = Object.assign({}, actionInfo);
            routeAction.payload = data;
            this.localDate[routeAction.route] = data;
            delete routeAction.route;
            if (typeof waitFor == 'number') {
                this.waitFor = waitFor;
                this.count = 0;
                this.count += 1;
            }
            if (this.count == this.waitFor) {
                routeAction.payload = this.localDate;
                if (this.actions) {
                    routeAction.type = this.actions;
                }
                return routeAction;
            }
        }
    }
`

更新了答案
我做错了是试图立即从我的组件中获取多个动作的响应,这是不可能的,所以我改变了我的策略,使用多个api的单一动作,因为我创建了一个带路线和apis的json

`this.routeConfig = {
  "countriesCitesTimezone": [
                { route: 'countries', type: 'SUCCESS-COUNTRIES', param: '', reqHeader: false },
                { route: 'cities', param: '', reqHeader: false },
                { route: 'timezone', param: '', reqHeader: false }
            ]
}`  

所以无论什么时候我都要调用一个动作,我都会用一些配置调用这个动作,比如

`var apiInfo = {
      route: 'countriesCitesTimezone',
      params: []
    }
    this.props.registration(apiInfo)`  

然后由史诗

处理
`GetEpic = (action$) =>
            action$.ofType(Action.Get)
                .switchMap(({ payload }) => {
                   let requests = this.routesConfig[payload.route];
                   return Observable.forkJoin(
                    requests.map((d, ind) => {
                        let param = d.param;
                        if (payload.params.length > 0) {
                            param = payload.params[ind];
                        }
                        return (HttpService.get(d.route, param, d.reqHeader));
                    })
                ).map((x) => {
                    console.log(x);
                    let result = {};
                    requests.map((d, ind) => {
                        result[d.route] = x[ind]
                    })
                    return ({
                        type: requests[0].type,
                        payload: result
                    })
                })
                })`

1 个答案:

答案 0 :(得分:0)

我认为您要找的是mergeMap,而不是switchMap

switchMap将:

  

将每个源值投影到一个Observable,该Observable在输出Observable中合并,仅从最近投影的Observable中发出值。

因此,在使用switchMap()时,类型Action.Get的每个新操作都会阻止先前服务调用的响应发出,如果它仍处于待处理状态。

此外,假设您的服务电话返回Promise,您应该考虑将HttpService.post()电话打包在Observable.fromPromise()中。我相信您收到Actions must be plain objects...错误的原因是因为您发出Promise,然后将其发送到商店。