我正在尝试在进行网络调用时使用CurrentValueSubject创建刷新事件。因此,每当网络请求失败时,我都可以按按钮再次提出请求,但由于失败事件将终止发布者,并且使其不再起作用,因此无法使其正常工作。
import Combine
import SwiftUI
struct ContentView: View {
@ObservedObject var viewModel: TestViewModel = TestViewModel()
var body: some View {
Button("Test", action: viewModel.test)
Button("Refresh", action: viewModel.refresh)
}
}
class TestViewModel: ObservableObject {
var bag = Set<AnyCancellable>()
private let changeSubject = CurrentValueSubject<Void, Never>(())
func test() {
changeSubject
.flatMap { self.networkPublisher }
.sink(
receiveCompletion: {
switch $0 {
case .failure:
print("Failure")
case .finished:
print("Finished")
}
},
receiveValue: {
print("Value: \($0)")
}
)
.store(in: &bag)
}
func refresh() {
changeSubject.send(())
}
var networkPublisher: AnyPublisher<String, Error> {
var url = URLRequest(url: URLComponents(string: "www.google.com")!.url!)
url.httpMethod = "GET"
return URLSession.shared
.dataTaskPublisher(for: url)
.tryMap { _ -> String in "Result" }
.receive(on: DispatchQueue.main)
.eraseToAnyPublisher()
}
}
要解决此问题,我可以使用.tryCatch { _ -> Just<String> in Just("Error") }
来捕获错误,这将阻止发布者终止。但是,为什么在发布者终止后它不起作用?比赛结束后我该如何工作?
答案 0 :(得分:1)
不因错误而终止管道的模式是使用flatMap
捕获错误:
changeSubject
.flatMap {
networkPublisher
.catch { _ in Empty() }
}
.sink {
print("Value: \($0)")
}
.store(in: &bag)
如您所见,.sink
仅收到String
的输出和Never
的错误,因为错误是在.flatMap
内完全处理的。
答案 1 :(得分:0)
您应该映射到新实例,而不是映射到发布者的单个实例。持久化的networkPublisher将触发其数据任务并完成操作,但是您将继续在flatMap中映射相同的完成的流。
MyService.exe install -username:DOMAIN\USER -password:xxxx start
应该是一个计算值,这样您每次通过都会返回一个新的发布者(和一个新的数据任务)。
from sklearn.metrics import mean_squared_error
list_ = [[489066.76, 300334.],
[227458.2, 200352. ],
[928249.59, 946729. ],
[339032.27, 350116. ],
[689668.21, 600322. ],
[489179.58, 577936. ]]
y_true = [y[0] for y in list_]
y_pred = [y[1] for y in list_]
mse = mean_squared_error(y_true, y_pred)
print(mse)
# 8779930962.14985
def my_mse(y_true, y_pred):
diff = 0
for couple in zip(y_true, y_pred):
diff+=pow(couple[0]-couple[1], 2)
return diff/len(y_true)
print(my_mse(y_true, y_pred))
# 8779930962.14985
看看Apple的this sample code。数据发布者本身是在flatMap的闭包内创建的,它强调了每次都是新实例的事实。