1
我工作的一個應用程序,我想實現使用RxSwift和RxCocoa包含URL如何實現串行網絡調用,那麼在RxSwift處理隊列?
- 下載JSON到X個文件以下
- 下載文件1,工藝文件1
- 下載文件2,工藝文件2
- 下載文件3,工藝文件3
...等
這裏的關鍵是,每個文件的處理已經下載一個文件之前完成。至少文件處理的順序必須按順序執行。如果我可以開始下載文件2,而文件1的處理,這將是真棒,但不是必需的。
我試過使用SerialDispatchQueueScheduler來做這個工作,但是由於文件大小不同,每個文件的下載在不同的時間完成,因此處理代碼的啓動順序與我開始下載的順序不同。
我可以很容易地實現這個沒有使用的Rx使用NSOperations之類的,但我想在這個應用程序中使用的Rx保持,因爲這是我在這個應用在其他地方使用。
下面我附帶一些代碼片段。爲了這個問題已經添加了評論。
.flatMap { [unowned self] (tasks: [DiffTask]) -> Observable<ApplyDiffStatus> in
return Observable.from(tasks)
.observeOn(self.backgroundScheduler) // StackOverflow: backgroundScheduler is a SerialDispatchQueueScheduler
.flatMapWithIndex({ [unowned self] (task, index) in
return self.fetchDiff(for: task, taskIndex: index, taskCount: tasks.count) // StackOverflow: Downloads a file from a URL
})
.catchError({ (error) -> Observable<DictionaryUpdater.DiffTaskProgress> in
observable.onError(error)
throw error
})
.map({ (diffTask : DiffTaskProgress) -> DiffTaskProgress.Progress in
// Stack Overflow: I've wrapped much of the progress observable in a Observable<UpdateProgress>
switch diffTask.progress {
case .started(currentTask: let currentTask, taskCount: let taskCount):
observable.on(.next(.fetchingDiff(progress: diffTask, currentDiff: currentTask, diffCount: taskCount)))
case .finished(data: _, currentTask: let currentTask, taskCount: let taskCount):
observable.on(.next(.fetchingDiff(progress: diffTask, currentDiff: currentTask, diffCount: taskCount)))
case .progress(completion: _, currentTask: let currentTask, taskCount: let taskCount):
observable.on(.next(.fetchingDiff(progress: diffTask, currentDiff: currentTask, diffCount: taskCount)))
}
return diffTask.progress
})
.flatMap({ [unowned self] (progress: DiffTaskProgress.Progress) -> Observable<ApplyDiffStatus> in
switch progress {
case .finished(data: let data, currentTask: let currentTask, taskCount: let taskCount):
return self.applyDiff(data, currentTask: currentTask, taskCount: taskCount) // StackOverflow: PROCESSES THE FILE THAT WAS DOWNLOADED
default:
return Observable.empty()
}
})
}