PromiseKit 在链接之前解包可选

PromiseKit unwrapping optional before chaining

刚开始使用 PromiseKit 6 Swift。我检查了一些示例并阅读了文档。我有一个看似微不足道的场景,但我无法绕过它。我有以下情况:

func addModel(_ model: Model, image: UIImage?, completion: @escaping (Error?) -> Void) {
   var modelToSet = model
   var id = ""

   firstly {
        serviceWrapper.setImage(image!)     
   }.map { path in
        modelToSet.imagePath = path
   }.then { [serviceWrapper]
        serviceWrapper.setModel(modelToSet)
   }.map { documentId in
        id = documentId
   }.then {
        CLLocationManager.promise()
   }.done { [serviceWrapper] location in
        serviceWrapper.setLocation(GeoPoint(latitude: location.lat, longitude: location.long), id: id)
   }.catch { error in
        completion(error)
   }
} 

如您所见,在这段伪代码中我强制展开图像。有什么想法只有在传递图像时才可以使用 setImage 方法启动链吗?否则直接从 setModel 开始。或者如果没有图像可能只是 return 空字符串?我在这里错过了什么?

Any ideas how I can start the chain with the setImage method only if there is an image passed?

您可以使用 guard 语句来检查图像是否为 nil。如果为nil,执行return需要的代码。如果不是,请使用扭曲的 image.

继续流程
func addModel(_ model: Model, image: UIImage?, completion: @escaping (Error?) -> Void) {
   var modelToSet = model
   var id = ""

   guard let image = image else {
       // insert code to return if needed
       return
   }

   firstly {
        serviceWrapper.setImage(image)     
   }.map { path in
        modelToSet.imagePath = path
   }.then { [serviceWrapper]
        serviceWrapper.setModel(modelToSet)
   }.map { documentId in
        id = documentId
   }.then {
        CLLocationManager.promise()
   }.done { [serviceWrapper] location in
        serviceWrapper.setLocation(GeoPoint(latitude: location.lat, longitude: location.long), id: id)
   }.catch { error in
        completion(error)
   }
} 

问了 PromiseKit 社区后,我得到了我需要的东西。所以这就是你可以用局部函数解决它的方法:

func addModel(_ model: Model, image: UIImage?, completion: @escaping (Error?) -> Void) {
    var modelToSet = model
    var id = ""

    func start() -> Promise<Void> {
        guard let image = image else {
            return Promise()
        }
        return serviceWrapper.uploadImage(image).map { path in
            dishToSet.imagePath = path
        }
    }

    firstly {
        start()
    }.then { [serviceWrapper]
        serviceWrapper.setModel(modelToSet)
    }.map { documentId in
        id = documentId
    }.then {
        CLLocationManager.promise()
    }.done { [serviceWrapper] location in
        serviceWrapper.setLocation(GeoPoint(latitude: location.lat, longitude: location.long), id: id)
    }.catch { error in
        completion(error)
    }
}