9

如何取消尚未履行或拒绝的承诺?

PromiseKit 的文档讨论了取消承诺,但我找不到如何执行此操作的具体示例。

鉴于:

currentOperation = client.load(skip: skip, query: nil)
currentOperation!.then { (items) in
   self.processItems(items: items, skip: skip, query: query)
}.catch { (error) in
    print("failed to load items - just retrying")
    self.loadIfNeeded(skip: skip, query: query, onlyInStock: onlyInStock)
}

如果查询更改(用户在搜索栏中输入一些文本)我想取消并丢弃currentOperation,开始一个新的承诺。

4

3 回答 3

6

为了取消一个承诺,你必须使用任何符合CancellableError协议的错误类型来拒绝它。这样,任何policy参数设置为的 catch 块allErrorsExceptCancellation都会让错误通过。

如果你需要一个 CancellablePromise,你可以继承 Promise 并实现一个 cancel() 函数,它会CancellableError在调用时拒绝。这是一个最小的实现:

https://gist.github.com/EfraimB/918eebdf7dd020801c72da1289c8d797

更新:

这是新 PromiseKit 版本 (6.4.1) 的更新

https://gist.github.com/EfraimB/3ac240fc6e65aa8835df073f68fe32d9

于 2018-01-08T14:24:52.800 回答
2

也许我的库 CancellablePromiseKit 对你有用:https ://github.com/johannesd/CancellablePromiseKit

它允许您像定义普通 Promise 一样定义 CancelablePromise,但添加了一个取消块。在该块中,您编写用于取消基础任务的代码。然后可以通过从外部调用cancellablePromise.cancel() 来取消承诺。

let cancellablePromise = CancellablePromise<String> { resolver in
    let currentOperation = client.load(skip: skip, query: nil)
    currentOperation.completion = { (value, error) in
        resolver.resolve(value, error)
    }
    return {
        // The cancel block
        currentOperation.stop()
    }
}

该库还重载了 when 和 race 以自动取消任务。

于 2018-05-20T17:35:24.813 回答
1

在 PromiseKit 7 中,用于func cancellize()PromiseorGuarantee转换为可以取消的 Promise:

currentOperation = client.load(skip: skip, query: nil)
let currentOperationCancellable = currentOperation!.then { (items) in
   self.processItems(items: items, skip: skip, query: query)
}.cancellize()
currentOperationCancellable.catch { (error) in
    print("failed to load items - just retrying")
    self.loadIfNeeded(skip: skip, query: query, onlyInStock: onlyInStock)
}

使用func cancel()orfunc cancel(with:)取消可取消的Promiseor Guarantee

currentOperationCancellable.cancel()
currentOperationCancellable.cancel(with: NSError(domain: "", code: 0, userInfo: nil))
于 2021-06-02T18:55:05.217 回答