![](/img/trans.png)
[英]Sending network request after bluetooth update while iOS app is in background
[英]Swift: Sending network request one after another
我想一個接一個地發送請求。 等待第一個響應發送第二個。
目前我使用這個:
DispatchQueue.global().async {
let dispatchGroup = DispatchGroup()
dispatchGroup.enter()
self.requestOne { _ in
dispatchGroup.leave()
}
dispatchGroup.wait()
dispatchGroup.enter()
self.requestTwo { _ in
dispatchGroup.leave()
}
dispatchGroup.wait()
dispatchGroup.enter()
self.requestTree { _, url in
user.profileImage = url?.absoluteString
dispatchGroup.leave()
}
dispatchGroup.wait()
self.requestFour { error in
completion(error)
}
}
它工作得很好,但我想知道是否有辦法在不使用的情況下使這個更清潔、更快捷
dispatchGroup.enter()
dispatchGroup.leave()
dispatchGroup.wait()
甚至是在類中包裝邏輯的模式
與其在請求完成中調用 dispatchGroup.leave() ,不如直接在那里調用下一個請求:
self.requestOne() { [weak self] _ in
guard let `self` = self else { return }
self.requestTwo() { [weak self] _ in
guard ..
self.requestThree...
}
}
或者按照評論中的建議,使用像 RxSwift 或 Combine 這樣的框架
編輯:
當某些請求會被其他請求調用時,根據不同的條件,您可以在requestXX
方法中檢查條件。 如果不滿足條件,只需調用完成並返回。
func requestTwoIfNeeded(paramsToCheckCondition, completion: ...) {
guard conditionMet else {
completion(state)
return
}
self.requestTwo(completion)
}
func sequentialRequests(completion: ...) {
self.requestOne() { [weak self] _ in
guard let `self` = self else { return }
self.requestTwoIfNeeded(conditionalParams) { [weak self] _ in
...
}
}
}
這個答案深受這篇文章的影響。 我盡可能刪除了不必要的代碼,並在需要的地方添加了代碼來組成一個工作游樂場。
import Foundation
import Combine
struct Agent {
func run<T: Decodable>(_ request: URLRequest, _ decoder: JSONDecoder = JSONDecoder()) -> AnyPublisher<T, Error> {
return URLSession.shared
.dataTaskPublisher(for: request)
.tryMap { result -> T in
return try decoder.decode(T.self, from: result.data)
}
.receive(on: DispatchQueue.main)
.eraseToAnyPublisher()
}
}
enum GithubAPI {
static let agent = Agent()
static let base = URL(string: "https://api.github.com")!
}
extension GithubAPI {
static func repos(username: String) -> AnyPublisher<[Repository], Error> {
let request = URLRequest(url: base.appendingPathComponent("users/\(username)/repos"))
return agent.run(request)
}
struct Repository: Codable {
let node_id: String
let name: String
}
static func issues(repo: String, owner: String) -> AnyPublisher<[Issue], Error> {
let request = URLRequest(url: base.appendingPathComponent("repos/\(owner)/\(repo)/issues"))
return agent.run(request)
}
struct Issue: Codable {
let url: URL
}
}
請注意,問題請求取決於回購請求。 實際請求由接收器調用觸發。
let user = "Alamofire"
let repos = GithubAPI.repos(username: user)
let firstRepo = repos.compactMap { $0.first }
let issues = firstRepo.flatMap { repo in
GithubAPI.issues(repo: repo.name, owner: user)
}
let token = issues.sink(receiveCompletion: { (_) in }) { (issues) in
print(issues)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.