问题描述
以下管道:
enum MyError: Error {
case oops
}
let cancel = Fail<Int, Error>(error: MyError.oops)
.print("1>")
.print("2>")
.sink(receiveCompletion: { status in
print("status>", status)
}) { value in
print("value>", value)
}
输出:
1>: receive subscription: (Empty)
2>: receive subscription: (Print)
2>: request unlimited
1>: request unlimited
1>: receive error: (oops)
2>: receive error: (oops)
status> failure(__lldb_expr_126.MyError.oops)
问题
但是,如果我在前一个管道中插入 receive(on:)
运算符:
enum MyError: Error {
case oops
}
let cancel = Fail<Int, Error>(error: MyError.oops)
.print("1>")
.receive(on: RunLoop.main)
.print("2>")
.sink(receiveCompletion: { status in
print("status>", status)
}) { value in
print("value>", value)
}
输出为:
1>: receive subscription: (Empty)
1>: receive error: (oops)
receive
操作符似乎使管道短路.我还没有看到其他发布者会发生这种情况,只是当我使用 Fail
或 PassthroughSubject
发布者时.
The receive
operator seems to short-circuit the pipeline. I haven't seen it happen for other publishers, just when I use a Fail
or PassthroughSubject
publisher.
这是预期的行为吗?如果是这样,原因是什么?
下面是创建与 receive(on:)
发布者一起使用的失败发布者的示例:
Here's an example of creating a failing publisher that works with the receive(on:)
publisher:
struct FooModel: Codable {
let title: String
}
func failPublisher() -> AnyPublisher<FooModel, Error> {
return Just(Data(base64Encoded: "")!)
.decode(type: FooModel.self, decoder: JSONDecoder())
.eraseToAnyPublisher()
}
let cancel = failPublisher()
.print("1>")
.receive(on: RunLoop.main)
.print("2>")
.sink(receiveCompletion: { status in
print("status>", status)
}) { value in
print("value>", value)
}
推荐答案
您可能会遇到这篇文章.显然, receive(on:)
将通过给定的调度程序异步发送 all 消息,包括订阅消息.因此,发生的事情是在订阅事件有机会被异步发送之前发送了错误,因此当下一个事件出现时,没有订阅者附加到 receive
发布者.
It's possible you're running into the same problem discussed in this post. Apparently receive(on:)
will send all messages asynchronously via the given scheduler, including subscription messages. So what's happening is the error is sent before the the subscription event has a chance to be sent asynchronously, and so there is no subscriber attached to the receive
publisher when the next event comes in.
但是,看来他们在 iOS 13.3的开发人员beta 1 :
这篇关于为什么Combine的receive(on :)运算符会误入错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!