#swift #event-loop #vapor
#swift #цикл событий #vapor
Вопрос:
Я новичок в кодировании в целом и особенно в концепции фьючерсов, поэтому терпение было бы оценено! Цель следующей функции — проверить, существует ли учетная запись в базе данных PostgreSQL. Если это произойдет, верните пустой UUID; если учетная запись не существует, создайте новую и верните ее UUID. Когда я пытаюсь запустить свой код, Cannot convert return expression of type 'EventLoopFuture<Account.idOut>' to return type 'Account.idOut'
рядом со строкой появляется ошибка .map { Account.idOut(id: account.id!) }
. Я уже посмотрел здесь и, похоже, не могу найти никакого решения этой проблемы. Любая помощь будет оценена, спасибо!!
func newAccount(req: Request) throws -> EventLoopFuture<Account.idOut> {
let input = try req.content.decode(Account.postAccount.self)
//check to see if account already exists
return Account.query(on: req.db)
.filter(.$email == input.email)
.first().map { checkAccount in
if checkAccount == nil {
let id = UUID()
let account = Account(id: id, fullName: input.fullName, email: input.email, password: input.password, type: input.type)
return account.save(on: req.db)
.map { Account.idOut(id: account.id!) }
} else {
return Account.idOut(id: UUID("00000000-0000-0000-0000-000000000000")!)
}
}
}
Комментарии:
1. Я голосую за закрытие этого вопроса, потому что его следует задавать в чате сообщества Vapor.
2. @imike звучит здорово. Возможно, это глупый запрос, но не могли бы вы направить меня в чат сообщества, о котором вы говорите? Спасибо 🙂
3. vapor.codes нажимает
Chat
кнопку в правом верхнем углу4. @imike, чат является временным и приносит пользу только OP. Ответ на вопрос о SO создает постоянный ресурс и приносит пользу всем, кто впоследствии сталкивается с той же проблемой.
5. @Nick это просто базовые знания о EventLoopFutures kirilltitov.com/en/blog/2019/futures
Ответ №1:
Короче говоря, вам нужно вернуть тот же тип, чтобы удовлетворить компилятор. Это определенно может немного сбить с if
толку / else
like yours, когда один возвращает future, а другой нет. Способ обойти это — вернуть будущее для обоих таким образом:
func newAccount(req: Request) throws -> EventLoopFuture<Account.idOut> {
let input = try req.content.decode(Account.postAccount.self)
//check to see if account already exists
return Account.query(on: req.db)
.filter(.$email == input.email)
.first().flatMap { checkAccount in
if checkAccount == nil {
let id = UUID()
let account = Account(id: id, fullName: input.fullName, email: input.email, password: input.password, type: input.type)
return account.create(on: req.db)
.map { Account.idOut(id: account.id!) }
} else {
return req.eventLoop.future(Account.idOut(id: UUID("00000000-0000-0000-0000-000000000000")!))
}
}
}
Важные моменты, на которые следует обратить внимание:
- Я изменил первое
map
на aflatMap
, поскольку вы возвращаете future внутри - Я использовал
create
вместоsave
для операции сохранения, поскольку вы предоставляете идентификатор, и это заставляет Fluent создавать модель. (Fluent обычно устанавливает идентификатор для вас) - Я завернул учетную запись в
req.eventLoop.future
— это возвращаетEventLoopFuture<Account.idOut>
результат, который удовлетворяет компилятору