如何使用RxJS发出多个HTTP请求,并将响应合并到一个有效负载中,并将其映射到另一个动作?

问题描述 投票:0回答:2

按照标题,我一直在尝试一种从动作有效负载进行多个HTTP调用,并基本上将所有结果合并到单个数组中,然后将结果作为有效负载映射到另一个动作的方法。

这是我现有的代码,它可以工作,但似乎不合并两个响应,而只关心请求响应中的最后一个响应,也许我使用的是错误的运算符,我只是拿起RxJS并尝试了其他事情学习,希望有人能够解释我要去哪里错了。

非常感谢您的帮助或指导。


{
    type: 'FETCH_DATA',
    payload: {
        key: 'standings',
        value: [
                'http://url-1',
                'http://url-2'
        ],
    })
}


// The epic is listening to the above action

const fetchDataEpic = action$ => action$.pipe(
    ofType('FETCH_DATA'),
    mergeMap(action => {
        const { key, value } = action.payload;
        if (Array.isArray(value) && value.length) {
            const makeRequest = value.map((x, i) => ajax.getJSON(value[i]))

            return (
                forkJoin(
                    makeRequest,
                    response => {
                        return ({
                            type: 'FETCH_DATA_SUCCEEDED',
                            payload: {
                                key,
                                value: response,
                            },
                        })
                    }
                )
            )
        }
    })
);

注意:两个请求的响应都是相同的JSON格式,具有相同的属性,但数据不同。

提前感谢

javascript reactjs rxjs observable rxjs6
2个回答
1
投票
似乎您正在使用rxjs的ajax函数,该函数应该已经可以观察到。在那种情况下,一旦所有可观察到的值都发出了,forkJoin应该给你两个值作为一个数组。然后您可以使用map函数将其添加到您的动作有效载荷中。

const requestArrays = [1, 2].map(i => { return rxjs.ajax.ajax.getJSON(`https://jsonplaceholder.typicode.com/posts/${i}`); }); rxjs.forkJoin(requestArrays) .pipe( rxjs.operators.tap(resp => { console.log('Part 1: Response so far: '); console.log(resp); }), rxjs.operators.map(value => { return { type: 'FETCH_DATA_SUCCEEDED', payload: { value } }; }), rxjs.operators.tap(resp => { console.log('Part 2: Result as a action payload: '); console.log(resp); }), ) .subscribe();
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.3/rxjs.umd.min.js"></script>

编辑:这里大致是您将如何实现它。

const action = { type: 'FETCH_DATA', payload: { value: [ '1', '2' ], } }; rxjs.of(action) .pipe( rxjs.operators.mergeMap(action => { const requestArrays = action.payload.value.map(i => { return rxjs.ajax.ajax.getJSON(`https://jsonplaceholder.typicode.com/posts/${i}`); }); return rxjs.forkJoin(requestArrays) .pipe( rxjs.operators.map(value => { return {type: 'FETCH_DATA_SUCCEEDED', payload: {value}}; }) ) }) ) .subscribe(console.log);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.3/rxjs.umd.min.js"></script>

0
投票
我不认为它只关心

last响应,但不关心first一个。

这是因为如果您想从forkJoin

自定义响应

,则第二个(或最后一个,以防第一个不是数组)参数(它是一个函数)接受多个参数] >,这是所提供请求的响应。因此,这是我为了获得整个响应数组而执行的更改。

/* ... */ forkJoin( makeRequest, (...response) => { return ({ type: 'FETCH_DATA_SUCCEEDED', payload: { key, value: response, }, }) } ) /*

编辑:将合并的响应发送到另一个操作

这可以通过使用tap运算符来实现,该运算符通常在必须处理副作用时使用。

( mergeMap(action => { ... }), tap(action => sendToOtherAction(action)) )

© www.soinside.com 2019 - 2024. All rights reserved.