2017-09-12 84 views
1

我工作的一個應用程序,我想實現使用RxSwift和RxCocoa包含URL如何實現串行網絡調用,那麼在RxSwift處理隊列?

  1. 下載JSON到X個文件以下
  2. 下載文件1,工藝文件1
  3. 下載文件2,工藝文件2
  4. 下載文件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() 
        } 
       }) 
     } 

回答

0

我管理通過使用concatMap操作者而不是

  .flatMapWithIndex({ [unowned self] (task, index) in 
       return self.fetchDiff(for: task, taskIndex: index, taskCount: tasks.count) // StackOverflow: Downloads a file from a URL 
      }) 

的concatMap操作者可確保第一觀察到正在發射任何多個信號之前完成來解決它。我不得不使用一些弄虛作假,因爲concatMap不拿出一個concatMapWithIndex,但它的工作原理:)