我试图开始Operation在侧面项目中使用s而不是在我的网络代码中散布基于闭包的回调以帮助消除嵌套调用.所以我正在做一些关于这个主题的阅读,我遇到了这个实现:
open class AsynchronousOperation: Operation {
// MARK: - Properties
private let stateQueue = DispatchQueue(label: "asynchronous.operation.state", attributes: .concurrent)
private var rawState = OperationState.ready
private dynamic var state: OperationState {
get {
return stateQueue.sync(execute: {
rawState
})
}
set {
willChangeValue(forKey: "state")
stateQueue.sync(flags: .barrier, execute: {
rawState = newValue
})
didChangeValue(forKey: "state")
}
}
public final override var isReady: Bool {
return state == .ready && super.isReady
}
public final override var isExecuting: Bool {
return state …Run Code Online (Sandbox Code Playgroud) 我在一个项目中成功地使用了 PromiseKit,直到 Xcode 11 beta 破坏了 PK v7。为了减少外部依赖,我决定废弃 PromiseKit。处理链式异步代码的最佳替代品似乎是使用新组合框架的 Futures。
我正在努力使用 Combine 复制简单的 PK 语法
前任。简单的 PromiseKit 链式异步调用语法
getAccessCodeFromSyncProvider.then{accessCode in startSync(accessCode)}.then{popToRootViewController}.catch{handleError(error)}
Run Code Online (Sandbox Code Playgroud)
我明白:
async/await 的 Swift 标准库实现将解决这个问题(async/await 尚不存在,尽管Chris Latter 本人有很多喋喋不休和参与)
我可以使用信号量进行复制(容易出错?)
flatMap 可用于链接 Futures
我想要的异步代码应该能够按需调用,因为它涉及确保用户登录。我正在努力解决两个概念性问题。
如果我将 Futures 包装在一个方法中,sink以处理结果,则该方法似乎在订阅者被调用之前超出了范围sink。
由于 Futures 只执行一次,我担心如果我多次调用该方法,我只会从第一次调用中得到旧的、陈旧的结果。要解决这个问题,也许我会使用 PassthroughSubject?这允许按需调用发布者。
问题:
//how is this done using Combine?
func startSync() {
getAccessCodeFromSyncProvider.then{accessCode in startSync(accessCode)}.catch{\\handle error here}
}
Run Code Online (Sandbox Code Playgroud) 我正在为我的 API 请求使用 Swift Combine。现在我面临的情况是,我想要将 4 个以上的并行请求压缩在一起。在我使用 Zip4() 运算符将 4 个请求压缩在一起之前。我可以想象您分多个步骤进行压缩,但我不知道如何为其编写 receiveValue。
这是我当前代码的简化,包含 4 个并行请求:
Publishers.Zip4(request1, request2, request3, request4)
.sink(receiveCompletion: { completion in
// completion code if all 4 requests completed
}, receiveValue: { request1Response, request2Response, request3Response, request4Response in
// do something with request1Response
// do something with request2Response
// do something with request3Response
// do something with request4Response
}
)
.store(in: &state.subscriptions)
Run Code Online (Sandbox Code Playgroud) 随着combine框架的到来,是不是还需要用到操作队列呢?例如,苹果在 WWDC 应用程序中几乎无处不在地使用操作队列。那么如果我们使用 SwiftUI 和 combine(异步编程),是否需要使用操作队列?
我的目标是使用合并来链接多个(此时为两个)网络调用,如果第一次调用失败则中断链接。
我有两种对象类型:CategoryEntity和SubcategoryEntity。每个CategoryEntity都有一个称为 的属性subcategoriesIDS。第一次调用时,我需要获取所有子类别,第二次调用时,我将获取所有类别,然后创建一个CategoryEntityViewModel.
CategoryEntityViewModel包含一个SubcategoryEntityViewModel基于 的CategoryEntity数组subcategoriesIDS。
只是为了更清楚:
SubcategoryEntityViewModel并存储在某处CategoryEntityViewModel是为每个获取的类别创建的。CategoryEntity该对象将使用一个对象和一个数组进行初始化,并在和存储的数组SubcategoryEntityViewModel之间找到过滤匹配的 IDsubcategoriesIDSSubcategoryEntityViewModel我现在的代码是:
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: …Run Code Online (Sandbox Code Playgroud) 我在控制器中有多个 api,成功响应后我必须重新加载UITableView.
现在我从两个 api 开始,第二个 api 依赖于第一个 usingBlockOperation和DispatchGroupin it。
首先在viewDidLoad:
getDataFromAllApis {
self.tableView.reloadData()
}
Run Code Online (Sandbox Code Playgroud)
然后我添加了方法:
func getDataFromAllApis(completion: @escaping (() -> Void)) {
let queue = OperationQueue()
let getFirstDataOperation = BlockOperation {
let group = DispatchGroup()
group.enter()
self.getFirstDataFromApi {
group.leave()
}
group.wait()
}
queue.addOperation(getFirstDataOperation)
let getSecondDataOperation = BlockOperation {
let group = DispatchGroup()
group.enter()
self.getSecondDataFromApi {
group.leave()
}
group.notify(queue: .main) {
completion()
}
}
queue.addOperation(getSecondDataOperation)
getSecondDataOperation.addDependency(getFirstDataOperation)
}
Run Code Online (Sandbox Code Playgroud)
我在这里面临的问题是 getSecondDataOperation 首先执行并返回到 tableview 重新加载部分。
我在这里遗漏了什么还是可以有不同的方法?任何帮助将不胜感激。 …