Swift PromiseKit:相当于when()顺序执行?

时间:2018-01-19 22:14:34

标签: ios swift promisekit

我正在使用PromiseKit和Swift,到目前为止它非常方便。它们提供的功能之一是when(),它允许您拥有任意数量的承诺数组,并且只有在完成所有承诺后才执行某些功能。

但是,数组中的promise是并行执行的。我还没有找到任何允许我按顺序执行它们的函数。我试图编写一个自己的递归函数,但它似乎没有按照它们在数组中的顺序执行promises,并且偶尔会出现“Promise deallocated”错误。请帮忙!

static func executeSequentially(promises: [Promise<Void>]) -> Promise<Void> {
    return Promise<Void> { fulfil, reject in
        var mutablePromises = promises
        if mutablePromises.count > 0 {
            mutablePromises.first!
                .then { _ -> Promise<Void> in
                    print("DEBUG: \(mutablePromises.count) promises in promise array.")
                    mutablePromises.remove(at: 0)
                    return executeSequentially(promises: mutablePromises)
                }.catch { error in
                    print("DEBUG: Promise chain rejected.")
                    reject(error)
            }
        } else {
            print("DEBUG: Promise chain fulfilled.")
            fulfil(())
        }
    }
}

2 个答案:

答案 0 :(得分:1)

这是一个扩展,它接受一组诺言并返回一个新的诺言,其中所有单独的诺言链接在一起以串行运行。我已修改此处找到的版本以与Swift 5 / PromiseKit 7 alpha配合使用:https://gist.github.com/kashifshaikh/416b9ffbd300eb680fad3641b6ec53ea

原始作者的随附帖子可以在这里找到:https://medium.com/@peatiscoding/promisekit-chaining-3c957a8ace24

import Foundation
import PromiseKit

extension Promise {
  
  /// Returns a single Promise that you can chain to. Wraps the chains of promises passed into the array into a serial promise to execute one after another using `promise1.then { promise2 }.then ...`
  ///
  /// - Parameter promisesToExecuteSerially: promises to stitch together with `.then` and execute serially
  /// - Returns: returns an array of results from all promises
  public static func chainSerially<T>(_ promises:[() -> Promise<T>]) -> Promise<[T]> {
    // Return a single promise that is fullfilled when
    // all passed promises in the array are fullfilled serially
    return Promise<[T]> { seal in
      var outResults = [T]()
      
      if promises.count == 0 {
        seal.fulfill(outResults)
      } else {
        let finalPromise:Promise<T>? = promises.reduce(nil) { (r, n) -> Promise<T> in
          return r?.then { promiseResult -> Promise<T> in
            outResults.append(promiseResult)
            return n()
          } ?? n()
        }
        
        finalPromise?.done { result in
          outResults.append(result)
          
          seal.fulfill(outResults)
        }.catch { error in
          seal.reject(error)
        }
      }
    }
  }
}

答案 1 :(得分:0)

我想您可能想要了解为什么您甚至想要这样的功能。考虑:

  • 如果需要一个承诺的结果作为下一个承诺的输入,那么它们必须是顺序的(then()

  • 如果一个promise的结果不需要作为下一个的输入,那么它们应该没有必要顺序,并且框架或平台应该最有效地使用并发(这个在大多数情况下意味着并行执行)

如果彼此之间没有任何输入/输出依赖关系的promises必须按特定顺序运行,则意味着您依赖于某种顺序的副作用。如果是这种情况,我会建议清理它,而不是使用顺序when()来解决下游问题。

如果这没有帮助,那么可以考虑在您的问题中添加信息,以解释为什么连续执行独立承诺很重要。您可以获得一些好的建议,无论是以另一种方式解决,还是使用现有when()then()功能的组合来完成您想要做的事情。