2017-09-12 15 views
1

私は、ファイルのX番号にRxSwiftとRxCocoaシリアルネットワークコールのキューを実装し、RxSwiftで処理する方法は?

  1. ダウンロードJSON含むURLを使用して、以下を実現したいアプリに取り組んでいます
  2. ファイルのダウンロード1、プロセスファイル1
  3. ファイルのダウンロード2、などのプロセスファイル2
  4. ファイルのダウンロード3、プロセスファイル3

...

ここで重要な点は、次のファイルをダウンロードする前に各ファイルの処理が完了していることです。少なくとも、ファイル処理の順序は順番に実行する必要があります。ファイル1が処理されている間にファイル2のダウンロードを開始できる場合、それはすばらしいことですが、必ずしも必要ではありません。

私はSerialDispatchQueueSchedulerを使用してこの作業を試みましたが、ファイルのサイズが異なり、各ファイルのダウンロードが異なる時点で完了しているため、ダウンロードが開始された順序とは異なる順序で処理コードが起動します。

NSOperationsなどを使用してRxを使用せずに簡単に実装できますが、このアプリでは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

私の代わりに

  .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演算子は最初の観察可能な、任意のより多くの信号を発する前に終了したことを確認します。 concatMapはconcatMapWithIndexが付属していないので、私はいくつかのトリッキーを使用しなければなりませんでしたが、それは動作します:)

関連する問題