首页 > 解决方案 > 如何按顺序链接 RxSwift Singles

问题描述

假设我要按顺序运行 3 种方法,并且入口点取决于整数(数字)。

func method1() -> Single<Void> {
    return .just(())
}

func method2() -> Single<Void> {
    return .just(())
}

func method3() -> Single<Void> {
    return .just(())
}

在常规 Swift 中会有这样的开关:

func doThings(startingFrom number: Int) -> Single<Void> {
    switch number {
    case 0:
        method1()
        fallthrough
    case 1:
        method2()
        fallthrough
    case 2:
        method3()
        fallthrough
    default:
        print("Finished")
    }

    return .just(())
}

但是考虑到 method1()、method2() 和 method3 是 Single 我认为 RxSwift 中应该有一种方法可以将它们链接起来而不会弄乱它们的执行顺序。

我想过这样的事情,但这是同步的,因此方法的执行顺序没有保证。

public func doThings(startingFrom number: Int) -> Single<Void> {
    var actions: [Single<Void>] = []
    switch number {
    case 0:
        actions.append(method1())
        fallthrough
    case 1:
        actions.append(method2())
        fallthrough
    case 2:
        actions.append(method3())
        fallthrough
    default:
        break
    }

    return Single
        .zip(actions)
        .do(onSuccess: { _ in
            Log.debug("Finished")
        })
        .mapToVoid()
}

对不起,如果我没有意义,我对 RxSwift 很陌生。如果有问题,请纠正我。

标签: iosswiftrx-swift

解决方案


您的解决方案非常接近。只需使用concat而不是,zip你就明白了。

我的错, Single 缺少concat运算符,因此您必须先转换为 Observable 或 Completable。这里有几个选项:

func doThings(startingFrom number: Int) -> Single<Void> {
    Observable.concat(
        [method1(), method2(), method3()]
            .dropFirst(number)
            .map { $0.asObservable() }
    )
    .toArray()
    .map(to: ())
    .do(onSuccess: { _ in
        print("Finished")
    })
}

func doThingsʹ(startingFrom number: Int) -> Single<Void> {
    Completable.concat(
        [method1(), method2(), method3()]
            .dropFirst(number)
            .map { $0.asCompletable() }
    )
    .andThen(.just(()))
    .do(onSuccess: { _ in
        print("Finished")
    })
}

推荐阅读