gpt4 book ai didi

swift - 我如何在循环中链接 Swift 中的 promise ?

转载 作者:搜寻专家 更新时间:2023-10-31 21:47:39 31 4
gpt4 key购买 nike

我正在构建一个基于 Swift 的 iOS 应用程序,它使用 PromiseKit处理 promise (尽管如果它使我的问题更容易解决,我愿意切换 promise 库)。有一段代码旨在处理有关覆盖文件的问题。

我的代码大致如下所示:

let fileList = [list, of, files, could, be, any, length, ...]

for file in fileList {
if(fileAlreadyExists) {
let overwrite = Promise<Bool> { fulfill, reject in
let alert = UIAlertController(message: "Overwrite the file?")
alert.addAction(UIAlertAction(title: "Yes", handler: { action in
fulfill(true)
}
alert.addAction(UIAlertAction(title: "No", handler: { action in
fulfill(false)
}
} else {
fulfill(true)
}
}

overwrite.then { result -> Promise<Void> in
Promise<Void> { fulfill, reject in
if(result) {
// Overwrite the file
} else {
// Don't overwrite the file
}
}
}

然而,这并没有达到预期的效果; for 循环“完成”的速度与遍历列表的速度一样快,这意味着 UIAlertController 在尝试将一个问题叠加在另一个问题上时会感到困惑。我想要的是链接的 promise ,以便只有在用户选择"is"或“否”(以及随后的“覆盖”或“不覆盖”代码已执行)后,才会执行 for 的下一次迭代循环发生。本质上,我希望整个序列是连续的。

考虑到数组的长度不确定,我如何链接这些 promise ?我觉得好像遗漏了一些明显的东西。

编辑:以下答案之一建议递归。这听起来很合理,尽管我不确定如果列表变长对 Swift 堆栈(这是在 iOS 应用程序中)的影响。理想的情况是,如果有一种结构可以通过链接到 promise 上来更自然地做到这一点。

最佳答案

一种方法:创建一个接受剩余对象列表的函数。将其用作 then 中的回调。在伪代码中:

function promptOverwrite(objects) {
if (objects is empty)
return
let overwrite = [...] // same as your code
overwrite.then {
do positive or negative action
// Recur on the rest of the objects
promptOverwrite(objects[1:])
}
}

现在,我们可能也有兴趣在没有递归的情况下执行此操作,只是为了避免在我们有数以万计的 promise 时破坏调用堆栈。 (假设 promises 不需要用户交互,并且它们都在几毫秒的数量级内解决,这样场景就很现实了)。

首先请注意,回调(在 then 中)发生在闭包的上下文中,因此它不能像预期的那样与任何外部控制流交互。如果我们不想使用递归,我们可能不得不利用一些其他 native 功能。

您首先使用 promises 的原因大概是您(明智地)不想阻塞主线程。那么考虑分拆第二个线程,其唯一目的是协调这些 promise 。如果您的库允许显式等待 promise ,只需执行类似

function promptOverwrite(objects) {
spawn an NSThread with target _promptOverwriteInternal(objects)
}
function _promptOverwriteInternal(objects) {
for obj in objects {
let overwrite = [...] // same as your code
overwrite.then(...) // same as your code
overwrite.awaitCompletion()
}
}

如果您的 promises 库不允许您这样做,您可以使用锁来解决它:

function _promptOverwriteInternal(objects) {
semaphore = createSemaphore(0)
for obj in objects {
let overwrite = [...] // same as your code
overwrite.then(...) // same as your code
overwrite.always {
semaphore.release(1)
}
semaphore.acquire(1) // wait for completion
}
}

关于swift - 我如何在循环中链接 Swift 中的 promise ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37913152/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com