Return Observer.create Не возвращается и код рядом с ним не работает с помощью RxSwift - PullRequest
1 голос
/ 05 октября 2019

Ну, я довольно плохо знаком с реактивным программированием. проблема в том, что у меня есть функция (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)

            })
    }

1 Ответ

1 голос
/ 05 октября 2019
  1. Создание функции наблюдаемого не требуется в функции B. Если вы хотите преобразовать одну наблюдаемую в другую, вы можете использовать map operator .

  2. Ошибка функции обработки в функции B. Ошибка будет обнаружена, но Observable никогда не будет завершена. В моем примере я использовал только побочный эффект для ошибки печати, поэтому ошибка будет распространяться и map не будет выполняться. Есть несколько стратегий для обработки ошибок в RxSwift .

  3. Функция B не нужна asObservable.

  4. Результат функции A (assingnedClass) не используется. Вероятно, реальный код был упрощен.

  5. В функции A. observer.onCompleted() после observer.onNext() нет * Ваша наблюдаемая не будет завершена и утилизирована вовремя.

Вот мой пример:

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)
    }
}

Кстати. Вы можете попробовать RxAlamofire для вас APIService, поэтому вам не нужно будет оборачивать запрос в Observable самостоятельно.

...