为什么Combine的receive(on :)运算符会误入错误? [英] Why does Combine's receive(on:) operator swallow errors?

查看:94
本文介绍了为什么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)
}

推荐答案

您可能会遇到

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开始,我们已更改了receive(on :)以及其他Scheduler运算符的行为,以同步向下游发送其订阅.以前,他们会将其异步"到提供的调度程序中.

As of developer beta 1 of iOS 13.3 (and associated releases for other platforms), we've changed the behavior of receive(on:) plus other Scheduler operators to synchronously send their subscription downstream. Previously, they would "async" it to the provided scheduler.

这篇关于为什么Combine的receive(on :)运算符会误入错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆