如何合并两个请求但 return 通用发布者?详情如下
How to combine two requests but return generic publisher? Details below
我有一个用于向服务器发送请求的通用函数。
现在,在我发送请求之前,我需要检查会话令牌是否已过期并在需要时更新它。
我的函数看起来像这样
func upload<T: Decodable>(some parameters here) -> AnyPublisher<T, Error>
我想在调用主请求之前检查并更新该函数内的令牌,但在这种情况下,我不能 return AnyPublisher<T, Error>
func upload<T: Decodable>(some parameters here) -> AnyPublisher<T, Error> {
if shouldUpdateToken {
let request = // prepare request
let session = // prepare session
return session.dataTaskPublisher(for: request)
.map(\.data)
.decode(type: SomeTokenObject.self, decoder: JSONDecoder())
// here I wanted to save token and continue with
// the previous request
// but using .map, .flatMap, .compactMap will not return needed publisher
// the error message I'll post below
.map {
// update token with [=11=]
// and continue with the main request
}
} else {
return upload() // this will return AnyPublisher<T, Error> so it's ok here
}
}
我在使用 .flatMap 时遇到这个错误
Cannot convert return expression of type 'Publishers.FlatMap<AnyPublisher<T, Error>, Publishers.Decode<Publishers.MapKeyPath<URLSession.DataTaskPublisher, JSONDecoder.Input>, SomeTokenObject, JSONDecoder>>' (aka 'Publishers.FlatMap<AnyPublisher<T, Error>, Publishers.Decode<Publishers.MapKeyPath<URLSession.DataTaskPublisher, Data>, SomeTokenObject, JSONDecoder>>') to return type 'AnyPublisher<T, Error>'
与 .map.
类似
我添加了另一个 returning AnyPublisher 的函数,并想像那样在 shouldUpdateToken
中使用
func upload<T: Decodable>(some parameters here) -> AnyPublisher<T, Error> {
if shouldUpdateToken {
return refreshToken() // returns AnyPublisher<Void, Error>
// now I need to continue with original request
// and I'd like to use something like
.flatMap { result -> AnyPublisher<T, Error>
upload()
}
// but using .map, .flatMap, .compactMap will not return needed publisher
// the error message I'll post below
} else {
return upload() // this will return AnyPublisher<T, Error> so it's ok here
}
}
对于平面地图:
Cannot convert return expression of type 'Publishers.FlatMap<AnyPublisher<T, Error>, AnyPublisher<Void, Error>>' to return type 'AnyPublisher<T, Error>'
对于地图:Cannot convert return expression of type 'Publishers.Map<AnyPublisher<Void, Error>, AnyPublisher<T, Error>>' to return type 'AnyPublisher<T, Error>'
也许我需要换一种方法?
我在应用程序周围有很多请求,因此在一个地方更新令牌是个好主意,但如何才能完成?
这里是refreshToken()
函数
func refreshToken() -> AnyPublisher<Void, Error> {
let request = ...
let session = ...
return session.dataTaskPublisher(for: request)
.map(\.data)
.decode(type: SomeTokenObject.self, decoder: JSONDecoder())
.map {
// saved new token
}
.eraseToAnyPublisher()
}
你快到了。您需要 eraseToAnyPublisher()
来擦除 returned 发布者。
请记住,像 .flatMap
(或 .map
和其他人)这样的运算符 return 他们自己的发布者,就像您在错误 Publishers.FlatMap<AnyPublisher<T, Error>, AnyPublisher<Void, Error>>
中看到的类型 - 您需要类型擦除:
func upload<T: Decodable>(some parameters here) -> AnyPublisher<T, Error> {
if shouldUpdateToken {
return refreshToken() // returns AnyPublisher<Void, Error>
.flatMap { _ -> AnyPublisher<T, Error> in
upload()
}
.eraseToAnyPublisher() // <- type-erase here
} else {
return upload() // actually "return"
}
}
(并确保您不会在没有任何停止条件的情况下不断地递归调用相同的 upload
函数)
我有一个用于向服务器发送请求的通用函数。 现在,在我发送请求之前,我需要检查会话令牌是否已过期并在需要时更新它。
我的函数看起来像这样
func upload<T: Decodable>(some parameters here) -> AnyPublisher<T, Error>
我想在调用主请求之前检查并更新该函数内的令牌,但在这种情况下,我不能 return AnyPublisher<T, Error>
func upload<T: Decodable>(some parameters here) -> AnyPublisher<T, Error> {
if shouldUpdateToken {
let request = // prepare request
let session = // prepare session
return session.dataTaskPublisher(for: request)
.map(\.data)
.decode(type: SomeTokenObject.self, decoder: JSONDecoder())
// here I wanted to save token and continue with
// the previous request
// but using .map, .flatMap, .compactMap will not return needed publisher
// the error message I'll post below
.map {
// update token with [=11=]
// and continue with the main request
}
} else {
return upload() // this will return AnyPublisher<T, Error> so it's ok here
}
}
我在使用 .flatMap 时遇到这个错误
Cannot convert return expression of type 'Publishers.FlatMap<AnyPublisher<T, Error>, Publishers.Decode<Publishers.MapKeyPath<URLSession.DataTaskPublisher, JSONDecoder.Input>, SomeTokenObject, JSONDecoder>>' (aka 'Publishers.FlatMap<AnyPublisher<T, Error>, Publishers.Decode<Publishers.MapKeyPath<URLSession.DataTaskPublisher, Data>, SomeTokenObject, JSONDecoder>>') to return type 'AnyPublisher<T, Error>'
与 .map.
我添加了另一个 returning AnyPublishershouldUpdateToken
中使用
func upload<T: Decodable>(some parameters here) -> AnyPublisher<T, Error> {
if shouldUpdateToken {
return refreshToken() // returns AnyPublisher<Void, Error>
// now I need to continue with original request
// and I'd like to use something like
.flatMap { result -> AnyPublisher<T, Error>
upload()
}
// but using .map, .flatMap, .compactMap will not return needed publisher
// the error message I'll post below
} else {
return upload() // this will return AnyPublisher<T, Error> so it's ok here
}
}
对于平面地图:
Cannot convert return expression of type 'Publishers.FlatMap<AnyPublisher<T, Error>, AnyPublisher<Void, Error>>' to return type 'AnyPublisher<T, Error>'
对于地图:Cannot convert return expression of type 'Publishers.Map<AnyPublisher<Void, Error>, AnyPublisher<T, Error>>' to return type 'AnyPublisher<T, Error>'
也许我需要换一种方法? 我在应用程序周围有很多请求,因此在一个地方更新令牌是个好主意,但如何才能完成?
这里是refreshToken()
函数
func refreshToken() -> AnyPublisher<Void, Error> {
let request = ...
let session = ...
return session.dataTaskPublisher(for: request)
.map(\.data)
.decode(type: SomeTokenObject.self, decoder: JSONDecoder())
.map {
// saved new token
}
.eraseToAnyPublisher()
}
你快到了。您需要 eraseToAnyPublisher()
来擦除 returned 发布者。
请记住,像 .flatMap
(或 .map
和其他人)这样的运算符 return 他们自己的发布者,就像您在错误 Publishers.FlatMap<AnyPublisher<T, Error>, AnyPublisher<Void, Error>>
中看到的类型 - 您需要类型擦除:
func upload<T: Decodable>(some parameters here) -> AnyPublisher<T, Error> {
if shouldUpdateToken {
return refreshToken() // returns AnyPublisher<Void, Error>
.flatMap { _ -> AnyPublisher<T, Error> in
upload()
}
.eraseToAnyPublisher() // <- type-erase here
} else {
return upload() // actually "return"
}
}
(并确保您不会在没有任何停止条件的情况下不断地递归调用相同的 upload
函数)