Promise Kit如何调用递归函数?

How to call recursive function with Promise Kit?

我被困在某个地方再次调用相同的函数,因为多次调用它是解除分配的承诺。实际上,就我而言,我有 API 多个页面请求,我想用 promise 来调用它。我是按如下方式实现的。

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)

        }

    }

请提供正确的方法来再次调用相同的函数。

您应该 return 在您的 promise 中进行响应,然后在接下来的 .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

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

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)

        }

    }