使用 alamofire 实现 api 调用时遇到问题

问题描述 投票:0回答:1

我正在使用alamofire,使用for循环web 3调用,但问题是我改变了链,然后在web3调用cam中崩溃了应用程序,你解决了这个问题,或者任何人帮助我进行新的api调用,然后之前的所有异步调用停止,然后出现新的请求问题这行 group.addTask { retun wait web3wrapper.shared } 如何解决这个并发调用我共享了图像链接,请检查https://imgur.com/WmGRdcb

func processHistoryDetails(historyDetail: History) async -> [String: Any]? {
        let logHistoryCount = historyDetail.logHistory?.count ?? 0
        var processWeb3Call: [String: Any]?
            await withTaskGroup(of: [String: Any]?.self) {[weak self] group in
                guard let self = self else {return}
                for i in 0 ..< logHistoryCount {
                    let firstIndexDecodedEventParams = historyDetail.logHistory?[i].decodedEvent?.params?.firstIndex(where: { event in
                        event.name == "value"
                    }) ?? -1
                    if firstIndexDecodedEventParams != -1 {
                        let contractAddress = historyDetail.logHistory?[i].address
                        let value = historyDetail.logHistory?[i].decodedEvent?.params?[firstIndexDecodedEventParams].value ?? "0"
                        group.cancelAll()
                        group.addTask {
                            return await Web3Wrapper.shared.processValue(contractAddress: contractAddress!, value: value, chainId: self.activeChain.chainId, rpcUrl: self.activeChain.rpcUrl)
                        }
                    }
                }
                for await result in group {
                    if let result = result {
                        processWeb3Call = result
                    }
                }
            }
            return processWeb3Call
    }
swift asynchronous async-await uikit alamofire
1个回答
0
投票

这里有大量可能的改进(将

if let foo = foo {…}
简化为
if let foo {…}
;摆脱
-1
逻辑;
[weak self]
捕获模式没有按照您的想法进行操作;等等),但让我们重点关注关于“启动一堆异步请求,但取消所有先前的请求并仅保存最后一个请求的结果”。

取消群组后添加任务的想法行不通,因为正如文档所说,“如果您在取消群组后向群组添加任务,则该任务在添加到群组后会立即被取消。”

但是如果想法是取消除最后一个请求之外的所有请求,我建议:

  1. 只有一个任务会实际运行;
  2. 确定您真正想要运行哪一个,然后只启动那个,根本不费心启动所有其他的;因此
  3. 完全停用任务组模式,因为只有当您确实想同时运行多个任务时,这才有意义。

例如,您可以以相反的顺序循环遍历日志历史记录,识别通过您想要的任何标准的日志历史记录,然后仅返回该日志历史记录,而不是同时启动一堆您想取消的任务:

func processHistoryDetails2(historyDetail: History) async throws -> [String: Any]? {
    guard let logHistory = historyDetail.logHistory else { return nil }
    
    for log in logHistory.reversed() {
        if
            let param = log.decodedEvent?.params?.first(where: { $0.name == "value" }),
            let address = log.address
        {
            return await Web3Wrapper.shared.processValue(
                contractAddress: address, 
                value: param.value ?? "0", 
                chainId: activeChain.chainId, 
                rpcUrl: activeChain.rpcUrl
            )
        }            
    }
    
    return nil
}

注意,我小心翼翼地避免强制展开运算符,

!
,因为这可能会使应用程序崩溃。
guard let
if let
总是更好。因此,我没有强制解开地址,而是将其添加到
if let
子句中。

主题有很多排列,但无论如何,我们的想法是不要开始要取消的任务。

© www.soinside.com 2019 - 2024. All rights reserved.