需要异步结果时快速等待

时间:2019-09-09 14:24:26

标签: swift async-await semaphore

我正在学习如何使用完成处理程序和调度。有一个带有两个可选参数(groupNamegroupId)的函数。如果给出了groupName,则必须使用该名称来检索groupId

这是我尝试等待的方法,以便在继续操作之前需要完成该方法,但是信号量只是无限期地等待。

func getTaskId(uid: String, groupName: String?, groupId: String?, taskName: String, handler: @escaping (Array<String>?, Error?) -> Void) {
    var id: String? // this is groupId not task id *
    let semaphore = DispatchSemaphore(value: 0)
    if let groupName = groupName {
        getGroupId(uid: uid, groupName: groupName) {(groupId, groupIdErr) in
            if let err = groupIdErr {
                handler(nil, err)
                return
            } else {
                id = groupId!
                semaphore.signal()
            }
        }
    } else if let unwrappedId = groupId {
        id = unwrappedId
        semaphore.signal()
    } else {
        let err = xErrors.getTaskIdErr(message: "Failed to get group id")
        handler(nil, err)
        return
    }
    semaphore.wait()
    guard let finalId = id else {return} // groupId will be used now
    // use groupId to continue and get taskId...
}

做这样的事情的正确方法是什么?等待另一种方法的结果,但只需要if即可。

1 个答案:

答案 0 :(得分:0)

您正试图强制异步任务变得同步。不要那样做。

减少该函数以仅检索ID。

Fix

调用它,并在完成处理程序中处理ID

func getTaskId(uid: String, groupName: String?, groupId: String?, completion: @escaping (Result<String,Error>) -> Void) {
    if let groupName = groupName {
        getGroupId(uid: uid, groupName: groupName) { groupId, groupIdErr in
            if let err = groupIdErr {
                completion(.failure(err))
            } else {
                completion(.success(groupId))
            }
        }
    } else if let unwrappedId = groupId {
        completion(.success(unwrappedId))
    } else {
       let err = xErrors.getTaskIdErr(message: "Failed to get group id")
       completion(.failure(err))
    }
}

另一种方法是声明一个函数

getTaskId(uid: "1", groupName: "foo", groupId: nil) { result in 
   switch result {
   case .success(let groupId): 
      // do something with groupId...

   case .failure(let error): print(error)
   }

}

然后将func doSomething(with groupId : String) {} 更改为

getTaskId

并使用它

func getTaskId(uid: String, groupName: String, completion: @escaping (Result<String,Error>) -> Void) {
    getGroupId(uid: uid, groupName: groupName) { groupId, groupIdErr in
        if let err = groupIdErr {
            completion(.failure(err))
        } else {
            completion(.success(groupId))
        }
    }
}