问题描述
我被困在某个地方,以在promise中再次调用同一函数,并且由于调用了多次,所以它重新分配了promise。实际上,在我的情况下,我有带有多个页面请求的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,nil)
}
.catch(policy: .allErrors) { error in
print(error.localizedDescription)
}
}
请提供给我正确的方法,以在promise中再次调用同一函数。
解决方法
代替使用递归,您应该在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)
}
}
}
现在只需按如下所示的promise顺序调用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,nil)
}
.catch(policy: .allErrors) { error in
print(error.localizedDescription)
}
}