Запросы и составление карт с использованием Vapor - PullRequest
0 голосов
/ 30 сентября 2018

Я пытаюсь написать функцию, используя 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, когда этого не должно быть

1 Ответ

0 голосов
/ 01 октября 2018

Как сказал @nathan, это связано с тем, что ваш код асинхронный.Ваш .map обратный вызов похож на замыкание, которое вы передаете URLSession.dataTask, когда делаете запрос к внешнему API для приложения iOS.

Vapor использует немного другую асинхронную модель, чем та, которую вы используете в iOS, хотя,используя обещания и фьючерсы вместо закрытия обратного вызова.Вы можете прочитать о них в документации .

. В вашем случае вы хотите вернуть 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 значений, чтобы вам не пришлось их распаковывать принудительно.

...