【发布时间】:2020-05-17 23:45:25
【问题描述】:
我正在关注“Server Side Swift Vapor Edition”一书,并且正在尝试第 174 页的练习。
我有一个名为 Poll 的结构,定义如下:
struct Poll: Content, SQLiteUUIDModel, Migration {
var id: UUID?
var title: String
var option1: String
var option2: String
var votes1: Int
var votes2: Int
}
它被映射到一个带有 Fluent 的 SQLite 数据库中,我正在尝试编写一个给出这样一个发布请求的路由:
localhost:8080/polls/delete/
能够在数据库中找到 poll 对象,如果不存在则返回错误,如果存在则删除。这就是我目前解决问题的方式:
router.post("polls", "delete", UUID.parameter) { req -> Future<Poll> in
let id = try req.parameters.next(UUID.self)
return Poll.find(id, on: req).map(to: Poll.self) { poll in
guard let poll = poll else {
throw Abort(.notFound)
}
poll.delete(on: req)
return poll
}
}
让我们分解一下:
- 我读取了在 post 请求中传递的 UUID(例如 http://localhost:8080/polls/delete/FBF7FDC2-0ECB-4C1F-AD8F-A62DE68E531B)
- 我试图找到投票
- 如果 poll 对象为 nil(表示未找到),我会抛出 404 not found 错误
- 如果我找到它,我会删除投票并将其返回
这行得通。我可以使用这条路线删除民意调查。 但是我有一些疑问:
- 会不会是delete方法还是失败了? (例如,由于内部 SQLite 错误)
- 如果是,我可以等到投票实际删除后再返回吗?
问题是delete方法返回一个EventLoopFuture类型的对象。如果它是 tupe EventLoopFuture 的对象,我将能够轻松地将其映射到民意调查。但是由于模板参数是无效的,如果我这样修改代码:
router.post("polls", "delete", UUID.parameter) { req -> Future<Poll> in
let id = try req.parameters.next(UUID.self)
return Poll.find(id, on: req).flatMap(to: Poll.self) { poll in
guard let poll = poll else {
throw Abort(.notFound)
}
return poll.delete(on: req).flatMap(to: Poll.self) { poll -> EventLoopFuture<Poll> in
return poll
}
}
}
我收到一个语法错误:“无法将 'Void' 类型的值转换为闭包结果类型 'EventLoopFuture'”。看起来我无法将 EventLoopFuture 对象映射到 EventLoopFuture。问题只是我想在返回之前等待删除操作完成。有什么解决办法吗?
【问题讨论】:
-
return poll.delete(on: req).transform(to: poll) -
@imike,
transform忽略了现有的Future值,所以它会等到delete完成吗? -
transform 总是等待未来,所以它会等到
delete完成
标签: swift fluent vapor fluentsqlite