如何使用 Promise Kit 调用递归函数?

Posted

技术标签:

【中文标题】如何使用 Promise Kit 调用递归函数?【英文标题】:How to call recursive function with Promise Kit? 【发布时间】:2020-09-02 05:41:00 【问题描述】:

我被困在某个地方再次在承诺中调用相同的函数,并且由于多次调用它是解除分配承诺。实际上在我的情况下,我有多个页面请求的 API,我想用承诺来调用它。我是按如下方式实现的。

func fetchContacts() -> Promise<FPGetContactResponse?> 
            
        return Promise  seal in

            let contactrequest = FPGetContactRequest()
            contactrequest.pageNo = getAPICurrentPageNo(Api.API_CONTACTS) + 1
            contactrequest.pageSize = SMALL_PAGE_SIZE
            
               contactrequest.doGetContacts(parameter: [:], response:  (response) in
                print("Contacts Count : \(response.Contacts?.count ?? 0)")

                if(response.Contacts?.count ?? 0 != 0)
                    _ = self.fetchContacts()

                else
                    seal.fulfill(response)
                
               )
                (error) in
                   print(error.localizedDescription)
                seal.reject(error)

            
        
    

在上面的函数中,我检查联系人计数!= 0 然后我需要再次调用相同的函数。但不幸的是,这是解除分配承诺。

我像下面这样调用承诺序列。

func startSyncData(handler:@escaping SyncAPIHandler)
        firstly 
            self.fetchContacts().ensure 
                handler(false,0.5,nil)
            
        .then  data in
            self.fetchInteractions().ensure 
                handler(false,0.7,nil)
            
        .then  data in
            self.fetchAddresses().ensure 
                handler(false,0.8,nil)
            
        .then  data in
            self.fetchLookupQuery().ensure 
            

        
        .done  contacts -> Void in
            //Do something with the JSON info
            print("Contacts Done")
            handler(true,0.8,nil)
        
        .catch(policy: .allErrors)  error in
            print(error.localizedDescription)

        

    

请为我提供正确的方式在 promise 中再次调用相同的函数。

【问题讨论】:

【参考方案1】:

你应该在你的承诺中返回一个响应,而不是使用递归,并在下一个.then 中检查它,如果需要,再次调用fetchContacts

fetchContacts()
.then  response -> Promise<FPGetContactResponse> in
    if (response.Contacts?.count ?? 0 != 0) 
        return fetchContacts() // Make the second call
    
    return .value(response) // Return fullfilled promise

.then 
    ...

您还可以使用下一种方法为您的案例制作一个特殊的包装器 - https://github.com/mxcl/PromiseKit/blob/master/Documentation/CommonPatterns.md#retry--polling

【讨论】:

谢谢我没有尝试您的解决方案,但它可能与我实施的类似,请参阅我的回答。为您的努力 +1 点赞。 @DipenChudasama 是的,这个想法正在返回来自.then 的第二次尝试的新承诺。【参考方案2】:

我用以下解决方案实现了一些东西。

func syncContacts() -> Promise<FPGetContactResponse?> 
      return fetchContacts().then seal -> Promise<FPGetContactResponse?> in
        if(seal?.Contacts?.count ?? 0 != 0)
            return self.syncContacts()
        else
            return Promise.value(seal)
        
      
    

现在只需按承诺顺序调用syncContacts() 方法,如下所示。

 func startSyncData(handler:@escaping SyncAPIHandler)
        firstly 
            self.syncContacts().ensure 
                handler(false,0.5,nil)
            
        .then  data in
            self.syncInterections().ensure 
                handler(false,0.7,nil)
            
        .then  data in
            self.syncAddresses().ensure 
                handler(false,0.8,nil)
            
        .then  data in
            self.syncLookupQuery().ensure 
            

        
        .done  contacts -> Void in
            //Do something with the JSON info
            print("Contacts Done")
            handler(true,0.8,nil)
        
        .catch(policy: .allErrors)  error in
            print(error.localizedDescription)

        

    

【讨论】:

以上是关于如何使用 Promise Kit 调用递归函数?的主要内容,如果未能解决你的问题,请参考以下文章

如何重试 Promise 解决 N 次,尝试之间有延迟?

为啥无法编译递归 PromiseKit 函数?

将递归异步函数转换为 Promise

如何在 C++ 中的类中递归调用函数方法?

使用参数递归的数字阶乘(如参数列表中的函数调用)

如何在构造函数中调用promise对象来设置属性[重复]