我是一名Swift初学者,在Vapor框架中工作,开发了一个注册过程,该过程需要依次执行几个步骤。我遇到以下代码的问题,该Xcode指示标记行上存在错误:
func signup(_ req: Request) throws -> Future<RecordA> {
return try req.content.decode(RecordACreation.self).flatMap(to: RecordACreation.self) { recordACreation in
// Prevent a recordA email from being used twice.
RecordA(on: req).filter(\.email == recordACreation).first().map(to: RecordA.self) { optionalExistingRecordAByEmail in
if let _ = optionalExistingRecordAByEmail {
throw Abort(.unprocessableEntity, reason: "RecordA email already exists")
}
}.flatMap { // Xcode indicates there's an error here.
// Prevent an recordB email from being used twice.
return RecordB.query(on: req).filter(\.email == recordACreation.recordBEmail).first().map(to: RecordA.self) { optionalExistingRecordBByEmail in
if let _ = optionalExistingRecordBByEmail {
throw Abort(.unprocessableEntity, reason: "RecordB email already exists.")
}
}
}.flatMap {
// If the recordB's password could not be successfully hashed.
guard let recordBPassword = try? BCrypt.hash(recordACreation.recordBPassword) else {
throw Abort(.unprocessableEntity, reason: "Password was unhashed")
}
// Ensure a verification token is generated successfully.
guard let optionalVerificationToken = try? VerificationTokenService.generate(), let verificationToken = optionalVerificationToken else {
throw Abort(.unprocessableEntity, reason: "Verification token could not be generated.")
}
let recordA = RecordA(name: recordACreation.recordAName, email: recordACreation.recordAEmail)
return req.transaction(on: .sqlite) { conn in
// TODO: Send email on signup success.
return recordA.save(on: conn).map(to: RecordA.self) { savedRecordA in
guard let recordAId = recordA.id else {
throw Abort(.unprocessableEntity, reason: "Verification token could not be generated.")
}
_ = RecordB(name: recordACreation.recordBName, email: recordACreation.recordBEmail, password: recordBPassword, recordAId: recordAId, verificationToken: verificationToken).save(on: conn)
return savedRecordA
}
}
}
}
}
该错误显示为:
无法使用类型为'(()-> EventLoopFuture)'的参数列表调用'flatMap'
我不完全了解正确选择map
和flatMap
之间的机制,因此这可能是造成此问题的原因。有想法吗?
答案 0 :(得分:1)
问题是在map
查询之后的RecordA
调用:
RecordA(on: req).filter(\.email == recordACreation).first().map(to: RecordA.self) { optionalExistingRecordAByEmail in
if let _ = optionalExistingRecordAByEmail {
throw Abort(.unprocessableEntity, reason: "RecordA email already exists")
}
}
您将RecordA.self
传递给to
参数,该参数将闭包的返回类型设置为RecordA
。相反,您什么也不返回。您应该删除to
参数,它应该可以正常工作:
RecordA(on: req).filter(\.email == recordACreation).first().map { optionalExistingRecordAByEmail in
if let _ = optionalExistingRecordAByEmail {
throw Abort(.unprocessableEntity, reason: "RecordA email already exists")
}
}