我正在构建一个基于
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 } }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。