【问题标题】:Argument of type '(num: number) => void' is not assignable to parameter of type '(value: number, index: number) => ObservableInput<{}>''(num: number) => void' 类型的参数不能分配给 '(value: number, index: number) => ObservableInput<{}>' 类型的参数
【发布时间】:2018-08-15 17:58:02
【问题描述】:

我对 rxjs 函数有一些疑问。实际上,我向 http 服务器发出请求。我从 http 服务器接收数据的方式是两个步骤,因为每个请求只返回 10 个项目,而不是整个项目。每个请求都有页码,所以如果我总共有 100 个项目,我必须进行 10 次请求。因此,在逐个发出请求之前,我先提取总页数,然后循环请求与页数一样多的请求。为了做到这一点,我使用如下 switchMap 函数。

getItems(id: string) {
    return this.dataService.getPageNum(id).switchMap (
    (page_num: number) => { 

                for(let i=1; i<=page_num; i++) {
                    this.dataService.getItems(id, i).subscribe(
                        (data: Object) => {
                            this.items.push(data); 
                        }
                    )
                }
            }
        );
    }

它返回错误错误 TS2345:'(page_num: number) => void' 类型的参数不可分配给'(value: number, index: number) => ObservableInput' 类型的参数。类型 'void' 不可分配给类型 'ObservableInput'。

所以,我搜索了一些关于这个问题的信息,我发现了一些东西,

Angular 2 - RxJS Switch Map Issue

但我不明白什么问题和答案说得好。这意味着我应该把 Observable.empty() 让它工作?另外,我什至尝试返回 Observable.of(null) 和 Observable.empty(),它说即使我导入了该函数,类型 'typeof Observable' 上也不存在属性'empty'。

【问题讨论】:

    标签: observable switchmap


    【解决方案1】:

    很高兴您熟悉 rxjs。你有几个错误。

    live example

    1. 您在 switchMap 函数内没有返回任何内容。它期望你这样做(返回一个 observable),这就是 mergeMap、switchMap 和 concatMap 的目的,以平展地图。看看这个site,希望对你入门有帮助。

    2. 您必须从平面地图管理订阅,而不是在 switchMap 函数内部。所以这行是不正确的:

    this.dataService.getItems(id, i).subscribe(

    your.component.ts

     getItems(id: string) {
               return this.dataService.getPageNum(id)
                         .switchMap((page_num: number) => {
                             for(let i=1; i<=page_num; i++) {
                                 return this.dataService.getItems(id, i);
                             }
                         }).subscribe((data: Object) => {
                             this.items.push(data); 
                         });
             }
    
    1. 最后,由于 rxjs 核心团队 的建议是使用管道运算符,这是正确的解决方案,我的意思是 rxjs 方式:

    import { switchMap } from 'rxjs/operators';

    ...

    getItems(id: string) {
          return this.dataService.getPageNum(id)
                    .pipe(switchMap((page_num: number) => {
                        for(let i=1; i<=page_num; i++) {
                            return this.dataService.getItems(id, i);
                        }
                    })).subscribe((data: Object) => {
                        this.items.push(data); 
                    });
        }
    

    【讨论】:

    • 谢谢,现在我对switchMap的了解更清楚了。这里,getPageNum() 是外部 Observable,而 getItems() 是内部 Observable。在进行for循环时,返回新的Observable,并通过Observer的订阅观察返回的observable。是不是?
    • 虽然晚了,但它并没有像我预期的那样工作。我有点怀疑,因为它没有正确通过循环。
    • 这个循环,this.dataService.getItems(id, i);一页一页地浏览不同的页面。它返回 Observable 所以我必须订阅每个 getItems 循环。
    • 解决方案是正确的,您可以查看实时示例。它解决了您在此处发布的错误,如果您没有得到预期的结果,请发布新的问题/错误消息。
    猜你喜欢
    • 1970-01-01
    • 2017-07-29
    • 1970-01-01
    • 2020-04-04
    • 2020-06-19
    • 2019-10-23
    • 2020-06-19
    • 1970-01-01
    • 2017-01-05
    相关资源
    最近更新 更多