如何解决Observables 是否也像调用堆栈中的 Promise 一样以相同的方式执行?
说到 Javascript,我完全是个新手。请帮助我理解 Observables 的概念。
- Observable 是否有存储位置,类似于 Web API 请求在移动到回调队列之前如何保存在 Web API 环境中?
- 这是原始 observable 还是已从回调队列移动到调用堆栈的副本?
- Observables 的执行与调用堆栈中的 promise 有何不同?
- 调用堆栈是否必须为空才能执行 Observables?
- 是否可以与 Observables 一起运行正常的函数调用(即,它不断从实时环境中获取数据,而其余函数单独运行)?
- 如果我们不取消订阅 Observables 并且它们继续在调用堆栈中运行直到应用程序关闭会发生什么?
解决方法
- Observable 是否有存储位置,类似于 Web API 请求在移动到回调队列之前如何保存在 Web API 环境中?
否。它们通过触发它们的函数保存的对它们的引用保存在内存中。例如,如果您从 DOM 事件创建一个 observable,RxJS 将向 DOM 添加一个事件侦听器,该 DOM 持有对 observable 的引用。如果删除正在监听的 DOM 元素,垃圾收集器会从内存中收集 DOM 元素,从而允许事件处理程序进行垃圾收集,允许 observable 及其内部函数链进行垃圾收集,进而允许订阅回调要被垃圾收集的函数 - 前提是用户代码中没有单独保留对 observable 的引用。
- 这是原始 observable 还是已从回调队列移动到调用堆栈的副本?
基于对问题 1 的否定回答,该问题并非基于有效假设。
- Observables 的执行与调用堆栈中的 promise 有何不同?
Observable 不会被执行,它们是对象。在内部,它们记录了一个函数链,当外部函数通过向其提供数据来触发 observable 时调用该函数链。当然,外部函数可能是一个重复的定时器回调(想想Scheduler),或者一个可以重复也可以不重复的事件,或者一次promise回调。
Promise 具有一些相似之处,包括它们是位于内存中某处的对象。在内部,它们持有两个回调函数列表,如果承诺被履行或被拒绝,以及对承诺链中下一个承诺的 resolve
和 reject
引用。
与 observables 一样,单个 Promise 对象通过其 resolve
和 reject
函数保存在内存中,这些函数特定于 Promise 实例。与 observable 一样,promise 也可以通过对用户代码中保存的 Promise 对象的引用保存在内存中。
- 调用堆栈是否必须为空才能执行 Observables?
没有。如果 observable 是由异步任务触发的,则调用堆栈可能几乎是空的,除了一些与向 observable 对象提供数据相关的代码和负责运行在调用订阅者回调函数之前运行的函数链的内部代码。如果 observable 是同步触发的,谁知道调用堆栈上有什么。
5 是否可以与 Observables 一起运行正常的函数调用(即,它不断从实时环境中获取数据,而其余函数单独运行)?
是的,除了如果 observable 是从用户代码同步触发的,它不会返回到用户代码,直到所有订阅者回调都返回。
6 如果我们不取消订阅 Observables 并且它们继续在调用堆栈中运行直到应用程序关闭会发生什么?
Observable 不在调用堆栈中,也不由订阅回调函数保存在内存中。它们从数据源事件或函数中被调用,并在调用期间在调用堆栈中创建一个堆栈帧。
如果数据源没有释放对 observable 的引用,则 observable 对象只是坐在内存中而不做任何事情。如果引用 observable 的数据源不再保存在内存中,并且用户代码中没有保存对 observable 的引用,则该 observable 有资格从内存中进行垃圾回收。如果用户代码没有引用它(例如,如果它是一个内联匿名函数),那么订阅回调函数也将有资格从内存中收集。
请注意,JavaScript library 支持 observable。您不是从通用数据库或 fetch 或 HTTP API 直接接收 observable,而是从某个中间软件层接收 observable,这些软件层将向您发出的请求的响应包装到触发返回给您的 observable 的数据源中。
如果此答案包含不准确之处,我深表歉意,因为它基于 JavaScript 的知识以及 RxJS 的“行为良好”足以从文档中推断其逻辑的假设。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。