我正在尝试使用Swift和Vapor编写函数,但我不明白为什么一个语句要在另一个语句之前打印:
// Logout user
func logout(_ req: Request) throws -> Future<APIResponseMessage> {
let userID = self.checkAccessToken(req: req)
// Delete access token here
let apiResponseMessage = APIResponseMessage()
apiResponseMessage.message = "success"
apiResponseMessage.userID = userID
return apiResponseMessage.create(on: req)
}
func checkAccessToken(req: Request) -> Int {
let bearerAuthorization = req.http.headers.bearerAuthorization
guard let _bearerAuthorization = bearerAuthorization else {
// Works fine
print("no bearer incluced")
return 0
}
let _ = AccessToken.query(on: req).filter(\.accessToken == _bearerAuthorization.token).first().map(to: Int.self) { queriedAccessToken in
// This should be first
print("This gets printed second")
return queriedAccessToken!.userID!
}
// This should be second
print("This gets printed first")
return 0
}
谁能告诉我如何使第二条打印语句等到第一个打印语句完成?
现在,如果不是这种情况,则会导致我的注销功能与userID == 0
一起运行
答案 0 :(得分:2)
正如@nathan所说,这是由于您的代码是异步的。您的.map
回调类似于向iOS应用程序的外部API发出请求时传递给URLSession.dataTask
的闭包。
Vapor使用的异步模型与您在iOS中使用的异步模型稍有不同,使用的是Promise和Future而不是回调闭包。您可以阅读关于它们的in the docs。
在您的情况下,您想返回从userID
查询中获得的AccessToken
。为此,您首先需要将方法的返回类型从Int
更改为Future<Int>
。然后,您可以从方法中将其返回,而不是将.map
调用的结果分配给_
,
func checkAccessToken(req: Request) -> Future<Int> {
let bearerAuthorization = req.http.headers.bearerAuthorization
guard let _bearerAuthorization = bearerAuthorization else {
return req.future(0)
}
return AccessToken.query(on: req).filter(\.accessToken == _bearerAuthorization.token).first().map(to: Int.self) { queriedAccessToken in
return queriedAccessToken!.userID!
}
}
我建议您对queriedAccessToken
和userID
值进行错误处理,以免强行拆开它们。