如何在forkJoin或concatAll(),toArray()之后保留流

时间:2019-05-15 23:06:20

标签: typescript rxjs

为了学习,我正在尝试在例如forkjoin之后保留流。但是我想用管道(优雅的方式)来做。不仅恢复数组,然后再次重写from(array).subscribe。

我试图在管道内从中进行操作,但这不起作用。我也想知道(作为奖励问题)什么是在管道中的理想方法(在这种情况下,第一个管道,因为我假设会有2个管道),以便在forkJoin数组之前修改每个mock_post调用结果返回。

我创建了一个小模拟函数来模拟2s后的虚拟api返回值。

    private mock_post(url: string): Observable<object> {
        return from(timer(2000)).pipe(
            map(result => {
                return {id: 2, name: 'mock', source: url};
            })
        );
    }

使用ForkJoin的第一个测试用例(使用上述功能)



        const operations = [];
        operations.push(this.mock_post('/api/test/'));
        operations.push(this.mock_post('/api/test/2'));
        operations.push(this.mock_post('/api/test/3'));

        forkJoin(operations).pipe(

        )
            .subscribe(
                (next) => {
                    console.log(next);
                }
            );

使用concatAll()+ toArray()的第二个测试用例。

    const obs: Observable<any> = from(operations);
        obs.pipe(
            map(result => {
                // I want to modify the result here, and add something to the object or modify a property (for example)
                console.log(`result-> `, result); // This is(obviously, returning an observable, but how do I get the final value here?)

                result.name = 'mock_modified';

                return result;
            }),
            concatAll(),
            toArray()
        ).subscribe(
            (next) => {
                console.log(`-> NEXT`, next);
            },
            (error) => {
                console.log(`* ERROR`, error);
            },
            () => {
                console.log('=) COMPLETE');
            }
        );

如果任何人都可以在这里丢了光,那就太好了。我希望我能正确解释自己。

3 个答案:

答案 0 :(得分:1)

确实不需要使用运算符进行数组操作。您可以在地图上完成

 forkJoin(operations).pipe(            
            map((results: any) => 
               results.map(result=>({...result,name:'changed}))
),

答案 1 :(得分:0)

搜索更多后,我正在回答自己的问题。

(通过我使用RXJS6.5的方式)

对于test1,在进行forkjoin之后,我基本上通过管道传输了concatMap,并在其中执行了from(result),以从数组中模仿每个值。然后,映射每个单独的结果,仅测试返回的对象的更改并记录结果(如果不需要对该对象进行修改,则tap()可能会达到相同的效果。

在那之后,一个简单的toArray()只会给我1个单个数组。

    test1() {

        const operations = [];
        operations.push(this.mock_post('/api/test/'));
        operations.push(this.mock_post('/api/test/2'));
        operations.push(this.mock_post('/api/test/3'));

        forkJoin(operations).pipe(
            concatMap((result) => {
                return from(result);
            }),
            map((result: any) => {
                console.log(`resulting-> `, result);
                result.name = 'changed';
                return result;
            }),
            toArray()
        ).subscribe(
            (next) => {
                console.log(next);
            }
        );
    }

说。如果有人有更好的方法,或者有替代方法。

我全神贯注。

我将此问题标记为由我自己回答,因为(目前)它对我的要求有效。

我仍在掌握RXJS的所有概念,并试图以一种优雅的方式保持流。

干杯。

答案 2 :(得分:0)

这是您的代码的样子:

function mock_post(url: string): Observable<any> {
  return timer(2000).pipe( // <-- you don't need to wrap 'timer' with 'from'
    map(result => ({ id: 2, name: 'mock', source: url }))
  );
}

const operations = [];
operations.push(mock_post('/api/test/'));
operations.push(mock_post('/api/test/2'));
operations.push(mock_post('/api/test/3'));

forkJoin(operations).pipe(
  map((responses: any[]) => responses.map(r => { // <-- Use Array.map to tranform the values
    console.log('result->', r);
    r.name = 'mock_modified';
    return r;
  }))
).subscribe(next => console.log('forkJoin', next));

concat(...operations).pipe( // <-- Use concat to create your Observable instead of piping to concatAll
  map((result: any) => { // <-- you can modify the results here
    console.log('result->', result);
    result.name = 'mock_modified';
    return result;
  }),
  toArray()
).subscribe(
  next => console.log('-> NEXT', next),
  error => console.log('* ERROR', error),
  () => console.log('=) COMPLETE')
);