【问题标题】:RxJs getting original event inside subscribe without passing downRxJs 在订阅中获取原始事件而不传递
【发布时间】:2017-06-02 17:04:35
【问题描述】:

一点伪代码解释一下标题:

   Subject source = new Subject();

   function sendInNewResource(newNumber, anotherVariable) {
       source.next(newNumber);   
   }

   const newSource = source
     .map((myNumber) => myNumber++);

   newSource.subscribe((data) => {
       //How can I access myObject here?
   });

   sendInNewResource(1, {myObject});

我认为伪代码解释了我想做的一些事情。 到目前为止,我已经尝试过扩展 observable,但如果我这样做了,看起来好像我需要覆盖 observable 中的运算符。

我几乎想为活动提供元数据。

我不想将 myObject 向下传递,因为这是一个供外部使用的库,我将在我的代码库中订阅可观察对象,但链接可观察对象将在外部完成。

有人对如何实现这一点有任何想法吗?

对于上下文, 我正在尝试创建一个纯粹的 RxJs http 库,它允许我执行以下操作:

const server$ = RxHttpServer(server)

const api$ = server.filter((request) => request.url.startsWith('/api'));

const apiEndpoint$ = api.map(() => ({
   status: 400,
   body: 'this is an api endpoint',
   headers: {
   }
}));

// Inside my library, note the use of the response object that I don't have access to:
apiEndpoint.subscribe((dataToSend) => response.write(dataToSend))

这些对象的内部逻辑和处理已经写好了,只需要返回那个响应对象。

【问题讨论】:

  • 我对 RxJS 的了解是有限的,但是你不是必须将 myObject 作为参数传递给 next 吗? source.next(newNumber, myObject) 如果这不可能,你可以做一些参数解构source.next({newNumber, myObject})
  • @Baruch,这是我在这篇文章中试图避免的一件事,因为我不希望框架的用户必须为他们制作的每条链传递响应。如果你想象一个端点通过平面图调用另一个端点,你会立即失去响应,或者不得不在任何地方使用选择器函数,这对我来说有点破坏可用性:)
  • 您是否考虑将您需要的response 对象包装在一个可观察对象中?在这种情况下,您可以将combineLatestapiEndpoint$response$ 一起使用,然后在回调中访问这两个。
  • @atomrc,我想你可以这样做,但我不完全确定你会如何为每个请求创建一个新的 observable
  • 响应究竟来自哪里?根据创建方式,您可以创建一个主题并将每个 response 提供给该主题。

标签: javascript rxjs reactivex


【解决方案1】:

您可以使用 responseFor 帮助器,它会获取响应元数据并返回一个可观察的响应主题,每个 HTTP 请求都有一个。图书馆用户可以订阅它并将数据写入每个响应主题。虽然您在库中可以订阅相同的响应主题,并在完成后将其发送回客户端。比如:

// even better extending the Observable prototype
// const apiEndpoint$ = api$.mapResponseFor(...
const apiEndpoint$ = api$.map(responseFor({
   status: 400,
   body: 'this is an api endpoint',
   headers: {}
}));

apiEndpoint$.subscribe(response => {
  response.next(data)
  response.complete()
})

【讨论】:

  • 也许我没有正确理解您的意思,但是响应类型的主题不会真正起作用 - 如果我们有一个需要 2 秒响应的请求和另一个可以处理的请求立即,第一个(慢请求)将由第二个 observable 处理。同样,也许我完全错了, responseFor 方法会做什么? :)
  • 这取决于apiEndpoint$ 观察者做什么。如果慢意味着进行一些其他异步调用并在此之后完成响应,那就没问题了。异步调用将被安排,javascript 将立即从第一个观察者的代码返回,并为下一个观察者提供服务。如果慢意味着实际计算,则第一个观察者将阻塞,第二个观察者将不被服务。但这始终是 javascript 单线程的问题。您需要一些特定于平台的并发方式,即您可以将处理代码包装在 Web Worker 中。
  • 您可以做的另一件事是在每个响应主题上调用responseSubject.observeOn(Rx.scheduler.async)。这将确保当用户执行response.next(data) 时不会同步执行,从而给其他观察者一些时间来处理。但是,如果计算 data 的计算是同步的并且很长(就像在代码中休眠),它仍然会阻塞主 javascript 线程。
猜你喜欢
  • 2023-03-13
  • 2015-01-11
  • 2021-03-03
  • 2022-11-07
  • 2018-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多