You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RxSwift如何等待Observable完成后依次执行操作?

串行执行RxSwift动作序列的解决方案

Hey there! I totally get where you're coming from as a RxSwift newbie—getting the hang of all those operators can feel overwhelming at first. Let's fix your sequential execution issue right away.

The Problem with Your Current Code

When you use map here:

let something = actions.map { action in
    return do(action)
}

You end up with an Observable<Observable<Result>> (a stream of streams). If you subscribe to this, all the inner observables (from do(action: "do1"), do(action: "do2"), etc.) will start in parallel instead of waiting for the previous one to finish. That's why you're not seeing the sequential execution you want.

The Fix: Use concatMap Instead of map

To make each action run only after the previous one completes, swap out map for concatMap. This operator handles exactly what you need—it subscribes to each inner observable one at a time, waiting for the current one to finish before moving on to the next.

Here's the updated code:

let something = actions.concatMap { action in
    return self.do(action: action) // Don't forget `self` if this is in a class/struct
}

Alternative: Use concat() on Your Stream of Streams

If you already have an Observable<Observable<Result>> (like the one from your original map call), you can also use the concat() operator to flatten it into a single sequential stream:

let something = actions.map { action in
    return self.do(action: action)
}.concat()

This does the same thing as concatMap—just a slightly different approach depending on your use case.

Important Note: Ensure Inner Observables Complete

For concatMap or concat() to work correctly, each do(action:) call must return an observable that emits a completed event once its task is done. If your observable never completes, the sequence will get stuck on that first action forever.

For example, if you're simulating an async task, make sure to send onCompleted() after your result:

enum Result {
    case success
    case failure(Error)
}

func do(action: String) -> Observable<Result> {
    return Observable.create { observer in
        // Simulate async work (e.g., network call, file operation)
        DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
            print("Finished executing \(action)")
            observer.onNext(.success)
            observer.onCompleted() // Critical for sequential execution!
        }
        return Disposables.create()
    }
}

Testing It Out

When you subscribe to something, you'll see the print statements in order:

Finished executing do1
Finished executing do2
Finished executing do3

Perfect—exactly the sequential flow you wanted!

内容的提问来源于stack exchange,提问作者buhutz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:14:18