如何使用 PromiseKit 在 Swift 3 中手动触发 Promise

Posted

技术标签:

【中文标题】如何使用 PromiseKit 在 Swift 3 中手动触发 Promise【英文标题】:How to manually trigger Promise in Swift 3 with PromiseKit 【发布时间】:2017-09-12 12:28:59 【问题描述】:

我正在寻求开发一种同步服务,该服务在用户拉动刷新时触发。此同步服务将对服务器执行多个请求。如何在每个 API 调用完成后手动触发 PromiseKit 承诺?承诺的回调会立即被调用。

//MyViewController.swift
func refresh(sender: AnyObject)
    var promise = syncService.syncFromServer()
    promise.then response
        //This is called immediately, and I need it to wait until the sync is complete
        refreshControl?.endRefreshing()
        tableView.reloadData()
    


//SyncService.swift
func syncFromServer() -> Promise<AsyncResult>
    let promise = Promise(value: AsyncResult)
     var page = 1

    //Multiple API calls
    //let request1 = ...
    //let request2 = ...
    //let request3 = ...
    //How do I tell the returned promise to trigger the associated callbacks after the last API requests has been completed?

    //Another scenario I need to handle is when the amount of requests is not known ahead of time.
    while(true)
        var response = makeAnApiCall(page)

        //if the response body says no more data is available, break out of the while loop, and tell any promise callbacks to execute.
        //if(noMoreData)
        // how do I perform something like
        // promise.complete //This line needs to tell the `then` statement in `MyViewController` to execute.
        // break
        //else
        //  do something with response data
        //
        page = page + 1
    

    return promise

【问题讨论】:

手动触发promise是什么意思?如果您正确声明返回Promise 的函数,则在then 使用它时,它的行为与普通同步函数非常相似,因此如果立即调用“回调”,则您的函数有缺陷。请在您的问题中包含函数定义。 @DávidPásztor,我在syncFromServer 方法中添加了说明。有一种情况,我不会提前知道请求的数量。所以我需要返回一个承诺,它将在响应说结果为零后执行。所以在确定结果为零之后,我需要告诉 promise 回调执行,并跳出 while 循环。 【参考方案1】:

下面我提供了一个示例,说明在所有 syncService 调用都运行后,您应该如何结束刷新和更新 tableView。查看 PromiseKit 文档关于使用 'when'。

func refresh(sender: AnyObject)
    syncService.syncFromServer().then  response in
        refreshControl?.endRefreshing()
        tableView.reloadData()
    


//SyncService.swift
func syncFromServer() -> Promise<Void> 
    let request1 = methodReturningPromise1()
    let request2 = methodReturningPromise2()
    return when(fulfilled: [request1, request2])


private func methodReturningPromise1() -> Promise<Void> 
    return syncService.someDataCall().then  response -> Void in
        //do something here
    

【讨论】:

在不知道请求数量的情况下,我也可以返回一个promise吗?假设我有一个while(true) 循环,当返回预期的响应时它可能会短路。所以在满足某个条件后,我会跳出while 循环并告诉promise listeners 执行。 是的,如果为真,您可以返回 Promise(value: ()),否​​则返回返回承诺的方法,例如 methodReturningPromise1()

以上是关于如何使用 PromiseKit 在 Swift 3 中手动触发 Promise的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Combine + Swift 复制 PromiseKit 风格的链式异步流

Swift 2 Promisekit 3 链接 asyc 方法的疯狂

PromiseKit:如何在 ObjC 中进行重试/轮询?

PromiseKit 3 for Swift2 中的“when”是不是已重命名?

使用 PromiseKit 从 Objective C 到 Swift 的桥接

Swift 4 - 使用 PromiseKit 调用嵌套