加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-14 04:28:08 所属栏目:百科 来源:网络整理
导读:我正在构建一个基于 Swift的iOS应用程序,它使用 PromiseKit来处理承诺(尽管如果它让我的问题更容易解决,我可以切换到promise promise库).有一段代码旨在处理有关覆盖文件的问题. 我的代码看起来大致如下: let fileList = [list,of,files,could,be,any,lengt
我正在构建一个基于 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在尝试将一个问题叠加到另一个问题时会感到困惑.我想要的是链接的承诺,所以只有当用户选择“是”或“否”(并且后续的“覆盖”或“不覆盖”代码已经执行)才会进行下一次迭代循环发生.基本上,我希望整个序列是顺序的.

考虑到阵列长度不确定,我如何链接这些承诺呢?我觉得好像错过了一些明显的东西.

编辑:下面的答案之一建议递归.这听起来很合理,但如果列表增长很长,我不确定Swift的堆栈(这是在iOS应用程序中)的含义.理想的情况是,如果有一个构造通过链接承诺更自然地做到这一点.

解决方法

一种方法:创建一个获取剩余对象列表的函数.在那时使用它作为回调.在伪代码中:

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的原因是你(明智地)不想阻止主线程.然后,考虑剥离第二个线程,其唯一目的是协调这些承诺.如果您的库允许明确地等待承诺,那就做一些类似的事情

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
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读