Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript RxJS:带有数组的JSON数据,进一步处理流中的每个项_Javascript_Arrays_Angular_Rxjs_Reactive - Fatal编程技术网

Javascript RxJS:带有数组的JSON数据,进一步处理流中的每个项

Javascript RxJS:带有数组的JSON数据,进一步处理流中的每个项,javascript,arrays,angular,rxjs,reactive,Javascript,Arrays,Angular,Rxjs,Reactive,我收到一个HTTP响应,如果一切顺利,它包含一个编码为JSON的数组。 我想获取这个数组,过滤掉一些项,并将传递的项作为事件处理 到目前为止,我所做的是: return this._http.get(url) .map((res:Response) => res.json()) .map((data:any) => { if (!Array.isArray(data) || data.length == 0) {

我收到一个HTTP响应,如果一切顺利,它包含一个编码为JSON的数组。
我想获取这个数组,过滤掉一些项,并将传递的项作为事件处理

到目前为止,我所做的是:

    return this._http.get(url)
        .map((res:Response) => res.json())
        .map((data:any) => {
            if (!Array.isArray(data) || data.length == 0) {
                throw new Error("No items returned, URL: " + url);
            }
            let projects = <ProjectModel[]>service.fromJSONarray(data, this._http);
            return Observable.from(projects)
                .filter((project: ProjectModel) => project.parentProject == null)
                .subscribe(project -> ...)
        })
返回此。\u http.get(url)
.map((res:Response)=>res.json())
.map((数据:任意)=>{
如果(!Array.isArray(data)| | data.length==0){
抛出新错误(“未返回任何项目,URL:+URL”);
}
让projects=service.fromJSONarray(数据,this.\uHTTP);
可观察的回报。来自(项目)
.filter((项目:ProjectModel)=>project.parentProject==null)
.订阅(项目->…)
})
但是我不喜欢筑巢。我认为有一种方法可以做到这一点:

    return this._http.get(url)
        .map((res:Response) => res.json())
        .map((data:any) => {
            ...
            let projects = <ProjectModel[]>service.fromJSONarray(data, this._http);
            ???
        })
        .filter((project: ProjectModel) => project.parentProject == null)
        .subscribe(project -> ...)
返回此。\u http.get(url)
.map((res:Response)=>res.json())
.map((数据:任意)=>{
...
让projects=service.fromJSONarray(数据,this.\uHTTP);
???
})
.filter((项目:ProjectModel)=>project.parentProject==null)
.订阅(项目->…)

如何实现这一点?

任何时候,当你映射到一系列可观察对象时,你都应该思考

在您的示例中,这看起来像:

return this._http.get(url)
    .map((res:Response) => res.json())
    .flatMap((data:any) => {
        if (!Array.isArray(data) || data.length == 0) {
            throw new Error("No items returned, URL: " + url);
        }
        let projects = <ProjectModel[]>service.fromJSONarray(data, this._http);
        return Observable.from(projects);
    })
    .filter((project: ProjectModel) => project.parentProject == null)
    //...etc

假设您使用的是RxJS 5,则使用
concatAll()
及其未记录的特性可以更轻松地展平嵌套数组,即使
concatAll()
用于处理高阶观测值

let data = '[{"id":1},{"id":2},{"id":3},{"id":4}]';

Observable.of(data)
    .map(JSON.parse)
    .concatAll() // each object is emitted separately
    .map(p => p) // transform to ProjectModel
    .filter(p => true) // filter whatever you want
    .subscribe(v => console.log(v));
如果
service.fromJSONarray
只返回
ProjectModel
的一个实例,那么就可以这么简单。如果需要
service.fromJSONarray
返回数组,可以将其放在
map(JSON.parse)
concatAll()之间。此演示将打印到控制台:

{ id: 1 }
{ id: 2 }
{ id: 3 }
{ id: 4 }
但是,如果您从
服务.fromJSONarray
返回一个可观察对象,它会发出其他可观察对象,因为它需要执行一些额外的HTTP请求,那么您需要使用
concatMap()
flatMap()
,具体取决于您是否希望保持相同的项目顺序:

let data = '[{"id":1},{"id":2},{"id":3},{"id":4}]';

function fromJSONarray(arr) {
    return Observable.from(arr)
        .flatMap(p => Observable.of(p));
}

Observable.of(data)
    .map(d => fromJSONarray(JSON.parse(d)))
    .concatAll()
    .map(p => p) // transform to ProjectModel
    .subscribe(v => console.log(v));
结果是一样的

类似问题:

  • 所以
    concatAll()
    toArray()相反?整洁的
    
    let data = '[{"id":1},{"id":2},{"id":3},{"id":4}]';
    
    function fromJSONarray(arr) {
        return Observable.from(arr)
            .flatMap(p => Observable.of(p));
    }
    
    Observable.of(data)
        .map(d => fromJSONarray(JSON.parse(d)))
        .concatAll()
        .map(p => p) // transform to ProjectModel
        .subscribe(v => console.log(v));