本文介绍了为什么Combine的receive(on :)运算符会误入错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下管道:

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 :)运算符会误入错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-26 23:38