Combine中的链式网络调用顺序



我的目标是用Combine连接多个(此时两个(网络调用,如果第一个调用失败,则断开连接。

我有两种对象类型:CategoryEntitySubcategoryEntity。每个CategoryEntity都有一个称为subcategoriesIDS的性质。第一次调用需要获取所有子类别,第二次调用将获取所有类别,然后创建一个CategoryEntityViewModel数组。CategoryEntityViewModel包含一个基于CategoryEntitysubcategoriesIDSSubcategoryEntityViewModel数组。

更清楚一点:

  1. 获取子类别
  2. 提取类别
  3. 为每个提取的子类别创建一个SubcategoryEntityViewModel并存储在某个位置
  4. 为提取的每个类别创建CCD_ 11。此对象将使用CategoryEntity对象和SubcategoryEntityViewModel数组进行初始化,在subcategoriesIDS和存储的SubcategoryEntityViewModel数组之间筛选匹配ID

我现在的代码是:

class CategoriesService: Service, ErrorManager {
static let shared = CategoriesService()
internal let decoder = JSONDecoder()

@Published var error: ServerError = .none

private init() {
decoder.dateDecodingStrategyFormatters = [ DateFormatter.yearMonthDay ]
}

func getAllCategories() -> AnyPublisher<[CategoryEntity], ServerError> {
let request = self.createRequest(withUrlString: "(AppSettings.api_endpoint)/categories/all", forMethod: .get)
return URLSession.shared.dataTaskPublisher(for: request)
.receive(on: DispatchQueue.main)
.tryMap { data, response -> Data in
guard let httpResponse = response as? HTTPURLResponse, 200..<300 ~= httpResponse.statusCode else {
switch (response as! HTTPURLResponse).statusCode {
case (401):
throw ServerError.notAuthorized
default:
throw ServerError.unknown
}
}
return data
}
.map { $0 }
.decode(type: NetworkResponse<[CategoryEntity]>.self, decoder: self.decoder)
.map { $0.result}
.mapError { error -> ServerError in self.manageError(error: error)}
.receive(on: RunLoop.main)
.eraseToAnyPublisher()
}

func getAllSubcategories() -> AnyPublisher<[SubcategoryEntity], ServerError> {
let request = self.createRequest(withUrlString: "(AppSettings.api_endpoint)/subcategories/all", forMethod: .get)
return URLSession.shared.dataTaskPublisher(for: request)
.receive(on: DispatchQueue.main)
.tryMap { data, response -> Data in
guard let httpResponse = response as? HTTPURLResponse, 200..<300 ~= httpResponse.statusCode else {
switch (response as! HTTPURLResponse).statusCode {
case (401):
throw ServerError.notAuthorized
default:
throw ServerError.unknown
}
}
return data
}
.map { $0 }
.decode(type: NetworkResponse<[SubcategoryEntity]>.self, decoder: self.decoder)
.map { $0.result }
.mapError { error -> ServerError in self.manageError(error: error)}
.receive(on: RunLoop.main)
.eraseToAnyPublisher()
}
}

这些方法正在工作(sink是在另一个类中调用的,不认为它有用,所以不复制到这里(,但我找不到链接它们的正确方法。

使用Combine链接异步操作的方法是flatMap。在map函数中生成第二个发布者。请确保将任何需要的信息作为值传递到map函数中,以便第二个发布者可以使用它。有关基本示例,请参阅如何使用Combine+Swift复制PromiseKit风格的链式异步流。

最新更新