【问题标题】:RxSwift wait for observable to complete, and return observableRxSwift 等待 observable 完成,然后返回 observable
【发布时间】:2021-04-11 18:03:20
【问题描述】:

当我使用 loadMovies 函数时,只有在 ViewController 调用函数并处理它之后才能获得所需的电影,这个函数在 API 中

func loadMovies() -> Observable<[Movie]> {
    let obsMovies = self.APICall(genrePath: Movies.action, structType: Movie.self)
    return Observable.create{ observer -> Disposable in
        obsMovies.subscribe(
            onNext: { element in 
                      observer.onNext(element)
                      print(element) 
           }
        )
        observer.onCompleted()
        return Disposables.create()
    }
}

在 ViewController 中,我在 viewDidLoad 中调用这个函数


request.api.loadMovies()
    .debug()
    .subscribe(
        onNext:{ data in
            do {
                print(data)
            }
        },
        onError: { error in
            print(error)
        },
        onCompleted: {
            print("Completed")
        },
        onDisposed: {
            print("Disposed")
        }
    )
    .disposed(by: disposeBag)

得到这个输出

ViewController.swift:55 (viewDidLoad()) -> subscribed
ViewController.swift:55 (viewDidLoad()) -> Event completed
Completed
Disposed
ViewController.swift:55 (viewDidLoad()) -> isDisposed

[MovieTest.Movie(name: "Black Panther", year: "2018", rating: "83")]
[MovieTest.Movie(name: "AVENGERS: ENDGAME", year: "2019", rating: "90")]
[MovieTest.Movie(name: "MISSION: IMPOSSIBLE -- FALLOUT", year: "2018", rating: "88")]...

我想知道如何在处理之前等待函数获取电影。我想在 tableView 中显示所有内容。我是 RxSwift 的初学者,我相信有更好的方法来实现这一点,但目前我不知道。谢谢

【问题讨论】:

    标签: ios swift rx-swift


    【解决方案1】:

    所以有几个问题需要立即解决...obsMovies.subscribe() 返回一个您忽略的一次性用品。由于它嵌入的闭包需要返回一个一次性的,所以只返回一个订阅创建的而不是创建一个新的:

    func loadMovies() -> Observable<[Movie]> {
        let obsMovies = self.APICall(genrePath: Movies.action, structType: Movie.self)
        return Observable.create{ observer -> Disposable in
            let disposable = obsMovies.subscribe(
                onNext: { element in
                    observer.onNext(element)
                    print(element)
                }
            )
            observer.onCompleted()
            return disposable
        }
    }
    

    接下来,请注意 APICall(genrePath:structType:) 返回一个 Observable&lt;[Movie]&gt; 那么为什么不直接返回它而不是将其包装在另一个 Observable 中呢?

    func loadMovies() -> Observable<[Movie]> {
        return self.APICall(genrePath: Movies.action, structType: Movie.self)
    }
    

    哇,现在我有点想知道为什么loadMovies() 存在...?

    现在我已经完成了上述操作,这是我看到的输出:

    ViewController.swift:55 (viewDidLoad()) -> subscribed
    ViewController.swift:55 (viewDidLoad()) -> Event next([MovieTest.Movie(name: "Black Panther", year: "2018", rating: "83"), MovieTest.Movie(name: "AVENGERS: ENDGAME", year: "2019", rating: "90"), MovieTest.Movie(name: "MISSION: IMPOSSIBLE -- FALLOUT", year: "2018", rating: "88")])
    [MovieTest.Movie(name: "Black Panther", year: "2018", rating: "83"), MovieTest.Movie(name: "AVENGERS: ENDGAME", year: "2019", rating: "90"), MovieTest.Movie(name: "MISSION: IMPOSSIBLE -- FALLOUT", year: "2018", rating: "88")]
    ViewController.swift:55 (viewDidLoad()) -> Event completed
    Completed
    Disposed
    2021-04-11 20:05:08.356: Stuff.swift:55 (viewDidLoad()) -> isDisposed
    

    【讨论】:

    • 哦,我现在觉得自己好蠢,这真的很有意义。我花了最后一天试图弄清楚出了什么问题,我几乎在撞头的同时拆除了我的墙壁?。谢谢,存在 loadMovies 是因为我想创建多种返回类型,有一次我想用 APICall(genrePath:structType:) 获取电影,而在另一种情况下我想获取 Actors,我的参数命名现在没有意义,我只是想让这段代码工作。谢谢
    • 我把“我想...为什么不直接在呼叫站点呼叫那条线路呢?这是值得考虑的事情。
    猜你喜欢
    • 2016-09-15
    • 2018-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-28
    • 2018-08-06
    • 1970-01-01
    • 2021-06-20
    相关资源
    最近更新 更多