Vapor 如何将 EventLoopF​​uture<Type> 转换为 <Type>

Vapor how to transform EventLoopFuture<Type> to <Type>

我正在使用 Vapor Fluent 实现删除路由处理程序。

对于此处理程序,我想验证发送产品删除请求的 userproduct 的所有者,否则 Abort 是请求的所有者。

func deleteHandler(_ req: Request) throws -> EventLoopFuture<HTTPStatus> {
    let user = req.auth.get(User.self)
    return Product.find(req.parameters.get("productID"), on: req.db)
        .unwrap(or: Abort(.notFound))
        .flatMap { product in
            return product.$user.get(on: req.db).flatMapThrowing { owner in
                guard try user?.requireID() == owner.requireID() else {
                    throw Abort(.forbidden)
                }
                return try product.delete(on: req.db)
                    .transform(to: HTTPStatus.noContent) // error here
            }
        }
}

但是 Vapor 在 return try product.delete(on: req.db).transform(to: HTTPStatus.noContent) 处抛出一个错误说 Cannot convert return expression of type 'EventLoopFuture<HTTPResponseStatus>' to return type 'HTTPStatus' (aka 'HTTPResponseStatus')

我尝试使用 map({}) 再次链接,但没有帮助。使用 wait() 解决了错误,但引入了运行时错误。

感谢您的帮助!

问题是 .flatMapThrowing 没有抛出未来。 requireID() 在这种情况下有点矫枉过正。如果您按如下方式替换 throw 并因此删除 Throwing,它应该可以工作:

func deleteHandler(_ req: Request) throws -> EventLoopFuture<HTTPStatus> {
    let user = req.auth.get(User.self)
    return Product.find(req.parameters.get("productID"), on: req.db)
        .unwrap(or: Abort(.notFound))
        .flatMap { product in
            return product.$user.get(on: req.db).flatMap { owner in
                guard user?.id == owner.id else {
                    return request.eventLoop.makeFailedFuture( Abort(.forbidden))
                }
                return product.delete(on: req.db)
                    .transform(to: HTTPStatus.noContent)
            }
        }
}

我稍后从 delete 中删除了 try。我猜编译器不会因为之前的错误而将其报告为不必要的,但通常不需要。如果是的话,我的回答将会失败!