首页 > 解决方案 > Return Observer.create 不返回并且它旁边的代码不能使用 RxSwift

问题描述

好吧,我对反应式编程非常陌生。问题是,我有一个返回对象的函数(A),现在我有另一个函数(B),它从函数 A 订阅返回的对象,并且我使函数 B 也作为在该订阅中返回另一个对象,现在整个返回这个是不行的。我不知道为什么会这样。任何帮助,将不胜感激。感谢 功能 A

func getClassById(classId: Int) -> Observable<Bool> {
    return Observable.create{[weak self] observer -> Disposable in            Alamofire.request("URL", method:.get, parameters: nil, encoding: JSONEncoding.default, headers: self!.getRequestHeader())
            .validate()
            .responseJSON{ response in
                switch response.result {
                    do {
                        let assingnedClass = try JSONDecoder().decode(AssignedClassModel.self, from: data)
                        observer.onNext(true)
                    } catch {
                        observer.onError(error)
                    }
                case .failure(let error):
                    observer.onError(error)
                }
        }
        return Disposables.create()
    }
}

功能 B

func getAssignedClassData(classId: Int) -> Observable<[StudentModel]>  { 
    return Observable.create{[weak self] observer -> Disposable in // from here code is not going further.
    APIService.singelton
        .getClassById(classId: classId)
        .asObservable()
        .subscribe(onNext: { [weak self] assingnedClass in
            let studentsData = Array(Database.singleton.fetchStudents(byCLassId: classId))
            print(studentsData)
            observer.onNext(studentsData)
            }, onError: { error in
                print(error)
        }).disposed(by: self!.disposeBag)
        return Disposables.create()
        }
}

功能 B2

    func getAssignedClassData(classId: Int) -> Observable<[StudentModel]>  {
        return APIService.singelton
            .getClassById(classId: classId)
            .do(onError: { error in
                print(error)
            })
            .map({ [weak self] assingnedClass in
                return Array(Database.singleton.fetchStudents(byCLassId: classId))
// this code will not be triggered as it is after return. 
                let vc = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "tabBarVC") as? TabBarViewController
                let transition = CATransition()
                transition.duration = 0.5
                transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.default)
                transition.type = CATransitionType.fade
                self?.navigationController?.view.layer.add(transition, forKey: nil)
                self?.navigationController?.pushViewController(vc!, animated: true)

            })
    }

标签: iosswiftreactive-programmingrx-swift

解决方案


  1. 函数 B 中不需要创建 Observable。如果要将一个 observable 转换为另一个,可以使用mapoperator

  2. 函数 B 中存在错误处理问题。错误会被捕获,但 Observable 永远不会完成。在我的示例中,我只使用了打印错误的副作用,因此错误将被传播并且map不会运行。RxSwift中有一些错误处理策略。

  3. 功能 B 不需要asObservable

  4. assingnedClass不使用函数 A ( ) 的结果。可能真正的代码被简化了。

  5. 功能 A中没有observer.onCompleted()after observer.onNext()。您的 observable 不会及时完成和处置。

这是我的例子:

class StudentService {
    ...
    func getAssignedClassData(classId: Int) -> Observable<[StudentModel]> {
        return APIService.singelton
            .getClassById(classId: classId)
            .do(onError: { error in
                print(error)
            })
            .map { _ in Array(Database.singelton.fetchStudents(byCLassId: classId)) }
    }
}

class SomeController: UIViewController {
    ...
    func fetchStudentsAndPushViewController() {
        studentService
            .getAssignedClassData(classId: classId)
            .observeOn(MainScheduler.instance)
            .subscribe(onNext: { [weak self] _ in
                let vc = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "tabBarVC") as? TabBarViewController
                let transition = CATransition()
                transition.duration = 0.5
                transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.default)
                transition.type = CATransitionType.fade
                self?.navigationController?.view.layer.add(transition, forKey: nil)
                self?.navigationController?.pushViewController(vc!, animated: true)
            })
            .disposed(by: self!.disposeBag)
    }
}

顺便提一句。您可以为您尝试RxAlamofireAPIService ,这样您就不需要自己将请求包装到 Observable 中。


推荐阅读