简体   繁体   English

Swift 优化嵌套异步调用

[英]Swift Optimise nested async calls

I have this case where I need to make 3 nested async calls to receive the data I want.我有这种情况,我需要进行 3 次嵌套异步调用来接收我想要的数据。 So the second call needs data from the first one and the third one needs data from the second one.所以第二个调用需要第一个调用的数据,第三个调用需要第二个调用的数据。 I do not have a lot of cases like this.我没有很多这样的案例。 Only this one and another one with only two nested call so I was thinking about a pure swift solution without any external libraries but I'm open to everything.只有这个和另一个只有两个嵌套调用,所以我在考虑一个没有任何外部库的纯 swift 解决方案,但我对一切都开放。

Since I'm using Firebase, is it better to move this logic to CloudFunctions?由于我使用的是 Firebase,因此将此逻辑移至 CloudFunctions 是否更好? So to prepare it in the backend?那么要在后端准备它吗?

FirestoreService().fetchCollection(query: query) { (result: Result<[Request], Error>) in
    // do stuff
    FirestoreService().fetchCollection(query: query) { (result: Result<[Request], Error>) in
        // do stuff
            FirestoreService().fetchDocument(documentReference: documentReference) { (result: Result<Package, Error>) in
                // finish
            }
        }

    }
}

If you don't to used 3rd party library, then probably you want to consider wrap those operations inside some class, and utilise closure in imperative way.如果您不使用 3rd 方库,那么您可能想考虑将这些操作包装在一些 class 中,并以命令式的方式使用闭包。

here is the sample:这是示例:

class CustomFirestoreHandler {

    private var onFetchFirstQueryArrived: ((Result<[Request], Error>) -> ())? = nil
    private var onFetchSecondQueryArrived: ((Result<[Request], Error>) -> ())? = nil
    private var onFetchDocumentArrived: ((Result<Package, Error>) -> ())? = nil

    init() {

        onFetchFirstQueryArrived = { [weak self] (result: Result<[Request], Error>) in
            self?.executeSecondQuery()
        }

        onFetchSecondQueryArrived = { [weak self] (result: Result<[Request], Error>) in
            self?.executeFetchDocument()
        }
    }

    func executeQuery(completion: @escaping (Result<Package, Error>) -> ()) {

        self.onFetchDocumentArrived = completion

        FirestoreService().fetchCollection(query: query) { [weak self] (result: Result<[Request], Error>) in 

            // validate if some error occurred and do early return here, so that we don't need necessarily call second query.
            if (result.error == whatever) {
                 self?.onFetchDocumentArrived?(result)
                 return
            }

            self?.onFetchFirstQueryArrived?(result)
        }
    }

    private func executeSecondQuery() {
        FirestoreService().fetchCollection(query: query) { [weak self] (result: Result<[Request], Error>) in 

            // validate if some error occurred and do early return here, so that we don't need necessarily call fetch document.
            if (result.error == whatever) {
                 self?.onFetchDocumentArrived?(result)
                 return
            }

            self?.onFetchSecondQueryArrived?(result)
        }
    }

    private func executeFetchDocument() {
        FirestoreService().fetchDocument(documentReference: documentReference) { (result: Result<Package, Error>) in
            self?.onFetchDocumentArrived?(result)
        }
    }

}

And here's the usage of CustomFirestoreHandler above:这是上面CustomFirestoreHandler的用法:

let firestoreHandler = CustomFirestoreHandler()
firestoreHandler.executeQuery { (result: Result<Package, Error>) in
    // Handle `result` here...
}

I know it look complicated, but this is the only way I think (CMIIW) at the moment to prevent pyramid of dooms since swift doesn't have async await style(just like javascript does).我知道它看起来很复杂,但这是我认为(CMIIW)目前防止厄运金字塔的唯一方法,因为 swift 没有异步等待样式(就像 javascript 一样)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Swift Parse-嵌套调用问题 - Swift Parse - Nested Calls Issue 在 Swift 中,@MainActor 似乎被 withCheckedContinuation 继承,而不是其他异步调用,这是巧合吗? - Is it a coincidence that @MainActor seems to get inherited by withCheckedContinuation, but not other async calls, in Swift? 如果我嵌套了dispatch_async调用,会发生什么? - What will happen if I have nested dispatch_async calls? 在 Swift 中查找图像大小并进行优化 - Find image size and optimise in Swift iOS中的多个异步调用 - Multiple Async calls in iOS 两个异步调用的同步 - Synchronisation of two async calls Swift Functional Programming-与两个map调用相比,有没有更好的方法来翻译嵌套的for循环 - Swift Functional Programming - is there a better way to translate a nested for loop than two map calls 如何以编程方式为我的 UIPicker 和 UICollectionView 优化数据输入 Swift iOS - How to optimise data inputs for my UIPicker and UICollectionView programmatically Swift iOS 如何在创建新的 storyboard 时优化 swift 中的 memory? - How to optimise memory in swift while creating new storyboard? Swift:处理异步调用 - Swift: working with asynchronous calls
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM