1

サーバーにリクエストを POST するループがあります。

for (traineeId, points) in traineePointsDict {  
    // create a new point
    let parameters: NSDictionary = [
        "traineeId": "\(traineeId)",
        "numPoints": points,
        "exerciseId": "\(exerciseId)"
    ]

    DataManager.sharedInstance.api.points.request(.POST, json: parameters).success { data in
        if data.json["success"].int == 1 {
            self.pointCreated()
        } else {
            self.pointFailToCreate()
        }
    }.failure { error in
        self.pointFailToCreate()
    }
}

問題は、何らかの理由で最後のリクエストが失敗することです。これは、サーバーに同時に投稿するリクエストが多すぎることが原因であると推測しています。

これらのリクエストをチェーンして、前のリクエストが完了するのを待ってから次のリクエストを実行する方法はありますか?

私はPromiseKitを見てきましたが、これを実装する方法がよくわからず、簡単な解決策を探しています.

4

1 に答える 1

2

Siesta は、リクエストがキューに入れられる方法や、同時に実行されるリクエストの数を制御しません。次の 2 つの選択肢があります。

  1. アプリ側で制御するか、
  2. ネットワーク層で制御します。

最初にオプション 2 を調査します。きめ細かい制御はできませんが、より堅牢なオプションを安価に提供し、間違いを起こしにくくなります。URLSessionネットワーク層 (Siesta のデフォルト) としてを使用している場合は、 のHTTPMaximumConnectionsPerHostプロパティがURLSessionConfiguration必要な機能を果たしているかどうかを調べてください。(カスタム構成を Siesta に渡す例をいくつか示します。)

それがうまくいかない場合、#1の簡単なバージョンは、完了ハンドラーを使用してリクエストをチェーンすることです。

func chainRequests(_ queue: [ThingsToRequest])
  guard let thing = queue.first else { return }
  params = makeParamsFor(thing)
  resource.request(.POST, json: params)
    .onSuccess {
      ...
    }.onFailure {
      ...
    }.onCompletion { _ in
      chainRequests(queue[1 ..< queue.count])
    }
}

複数の重複するハンドラーを同じリクエストにアタッチでき、それらはアタッチした順序で呼び出されることに注意してください。Siesta は、結果に関係なく、completionブロックが常に呼び出されることを保証することにも注意してください。これは、各リクエストがクロージャー 1 と 3、またはクロージャー 2 と 3 のいずれかを呼び出すことを意味します。これが、このアプローチが機能する理由です。

于 2015-10-29T17:15:35.353 に答える