【问题标题】:Is Observables is also executed in the same way like promises in the call stack? [closed]Observables 是否也像调用堆栈中的 Promise 一样执行? [关闭]
【发布时间】:2021-08-17 22:14:15
【问题描述】:

在 Javascript 方面,我完全是新手。请帮助我理解 Observables 的概念。

  1. Observable 是否有存储位置,类似于 Web API 请求在移动到回调队列之前保存在 Web API 环境中的方式?
  2. 这是原始 observable 还是已从回调队列移动到调用堆栈的副本?
  3. Observables 的执行与调用堆栈中的 Promise 有何不同?
  4. 调用堆栈是否必须为空才能执行 Observables?
  5. 是否可以与 Observables 一起运行正常的函数调用(即,它不断从实时环境中获取数据,而其余的函数单独运行)?
  6. 如果我们不取消订阅 Observable 并且它们继续在调用堆栈中运行直到应用关闭,会发生什么情况?

【问题讨论】:

  • 你在说什么 observables 实现?
  • Promise 没有被执行,只有它们的处理程序被执行,我怀疑 observables 有什么不同。
  • @Bergi - 从标签中,“observables”是RxJS 库的一部分
  • @Bergi ex- 来自 HTTP 方法调用的 Observables。
  • @Bergi 我对此不太了解,但我认为 Observables 也是函数,订阅 observables 与调用函数非常相似。我只想知道假设我们正在从远程数据库(如 firebase)作为 Observables 获取用户登录状态,就调用堆栈中的执行而言,它与 fetch() 有何不同,后者返回承诺并由处理程序解决,以及他们如何从回调队列到调用堆栈,以及我在上面相同上下文中提出的任何其他问题。

标签: javascript es6-promise callstack event-loop redux-observable


【解决方案1】:
  1. Observable 是否有存储位置,类似于 Web API 请求在移动到回调队列之前保存在 Web API 环境中的方式?

不。它们通过引用它们被触发它们的函数保存在内存中。例如,如果你从一个 DOM 事件创建一个 observable,RxJS 会向 DOM 添加一个事件监听器,它持有对 observable 的引用。如果删除正在监听的 DOM 元素,则 DOM 元素会被垃圾收集器从内存中收集,从而允许事件处理程序被垃圾收集,允许 observable 及其内部函数链被垃圾收集,进而允许订阅回调要进行垃圾收集的函数 - 前提是用户代码中没有单独保留对 observable 的引用。

  1. 这是原始 observable 还是已从回调队列移动到调用堆栈的副本?

基于对问题 1 的否定回答,此问题不是基于有效假设。

  1. Observables 的执行与调用堆栈中的 Promise 有何不同?

Observables 没有被执行,它们是对象。在内部,它们记录了一个函数链,当外部函数通过向其提供数据来触发 observable 时调用该函数链。当然,外部函数可能是重复的计时器回调(想想调度程序),或者可能重复或不重复的事件,或者一次性承诺回调。

Promise 有一些相似之处,包括它们是位于内存某处的对象。在内部,它们包含两个回调函数列表,如果承诺被履行或拒绝,则要调用的回调函数以及 resolvereject 对承诺链中下一个承诺的引用。

像 observables 一样,各个 Promise 对象由它们的 resolvereject 函数保存在内存中,这些函数是 promise 实例特有的。与 observable 一样,promise 也可以通过对用户代码中保存的 Promise 对象的引用保存在内存中。

  1. 调用堆栈是否必须为空才能执行 Observables?

没有。如果 observable 由异步任务触发,则调用堆栈可能几乎是空的,除了一些与向 observable 对象提供数据相关的代码和负责运行在调用订阅者回调函数之前运行的函数链的内部代码。如果 observable 被同步触发,谁知道调用堆栈上有什么。

5 是否可以与 Observables 一起运行正常的函数调用(即,它会不断从实时环境中获取数据,而其余的函数是单独运行的)?

是的,除非 observable 是从用户代码同步触发的,否则在所有订阅者回调都返回之前,它不会返回到用户代码。

6 如果我们不取消订阅 Observable 并且它们继续在调用堆栈中运行直到应用关闭,会发生什么情况?

Observable 不在调用堆栈中,也不由订阅回调函数保存在内存中。它们从数据源事件或函数中调用,并在调用期间在调用堆栈中创建一个堆栈帧。

如果数据源不释放它对可观察对象的引用,则可观察对象只是坐在内存中而不做任何事情。如果引用 observable 的数据源不再保存在内存中,并且用户代码中没有保存对 observable 的引用,则 observable 将有资格从内存中进行垃圾回收。如果用户代码没有对订阅回调函数的引用(例如,如果它是内联匿名函数),订阅回调函数也将有资格从内存中收集。

请注意,JavaScript library 支持 observables。您不会直接从通用数据库或 fetch 或 HTTP API 接收 observable,而是从某个中间软件层接收 observable,该中间软件层将对您发出的请求的响应包装到触发返回给您的 observable 的数据源中。


如果此答案包含不准确之处,我深表歉意,因为它基于 JavaScript 知识以及 RxJS 的“行为良好”足以从文档中推断其逻辑的假设。

【讨论】:

  • 非常感谢您的详细回答。
猜你喜欢
  • 2014-03-04
  • 1970-01-01
  • 2012-10-12
  • 1970-01-01
  • 2017-11-04
  • 2012-09-06
  • 1970-01-01
  • 2012-09-03
  • 2021-08-06
相关资源
最近更新 更多