所以我正在尝试在我的一个 Vapor 端点中调用第二个端点。我有一个端点只是一个获取并且效果很好:
router.get("status") { req -> Future<ConnectionResponse> in
let client = try req.make(Client.self)
let response = client.get("https://url.com/endpoint/")
return response.flatMap(to: ConnectionResponse.self, { response in
return try response.content.decode(ConnectionResponse.self)
})
}
这将正确返回连接响应 json。当我尝试做同样的事情时,但在需要一些参数的 POST 中,我无法弄清楚为什么编译器不允许我运行:
router.post("purchase") { req -> Future<ConnectionResponse> in
return try req.content.decode(PurchaseRequest.self).map(to: ConnectionResponse.self, { response in
let client = try req.make(Client.self)
let response = client.get("https://url.com/endpoint/")
return response.flatMap(to: ConnectionResponse.self, { response in
return try response.content.decode(ConnectionResponse.self)
})
})
}
它失败了,flatMap
说Cannot convert return expression of type 'EventLoopFuture<ConnectionResponse>' to return type 'ConnectionResponse'
.
如您所见,除了 POST 参数的初始解码外,purchase
GET 调用与status
相同。我做错了什么?
只需替换
return try req.content.decode(PurchaseRequest.self).map(to: ConnectionResponse.self, { response in
跟
return try req.content.decode(PurchaseRequest.self).flatMap(to: ConnectionResponse.self, { response in
完整的工作代码可能如下所示
router.post("purchase") { req -> Future<ConnectionResponse> in
return try req.content.decode(PurchaseRequest.self).flatMap { response in
let client = try req.make(Client.self)
let response = client.get("https://url.com/endpoint/")
return response.flatMap { response in
return try response.content.decode(ConnectionResponse.self)
}
}
}
那么map
和flatMap
有什么区别呢?
如果Future<Something>
下一个结果,则使用flatMap
,例如:
someDatabaseCall(on: container).flatMap { databaseResult1 in
/// it will return Future<DatabaseResult>
/// that's why we use `flatMap` above instead of `map`
return anotherDatabaseCall(on: container)
}
map
用于非未来结果,例如:
someDatabaseCall(on: container).map { databaseResult1 in
/// it will return non-future result
/// that's we use `map` above instead of `flatMap`
return "hello world" // just simple string
}
什么是Future<>
?它只是一个承诺,就像一个带有回调的对象。