ES7 之 Promise vs Observable

阅读时长 5 分钟读完

在现代的前端开发中,异步编程是一种非常常见的需求。ES6 中引入的 Promise 已经在大多数场景中代替了传统的回调函数,但是在某些异步场景下,它仍然存在一些缺点和限制。ES7 中,Observable 被引入成为一种新的异步解决方案,它的强大和灵活性使其在某些场景下,比 Promise 更加适用。

Promise 的特点和限制

Promise 是由 ECMAScript 6 引入的一种新的异步编程方式。它的主要特点是:

  • 通过 then() 方法实现链式调用;
  • 不需要额外的参数来传递成功或失败的数据,而是通过 resolve() 和 reject() 方法传递;
  • 可以通过 catch() 方法捕捉异常;
  • 只能返回单个值或者错误。

Promise 的优点是它比传统的回调函数更加清晰和简洁,能够清晰地表达异步操作成功或失败的状态,并能够简单地处理异常。但是,Promise 还存在一些限制:

  • Promise 只能携带一次结果,无法处理多次返回结果的情况;
  • Promise 无法表示中间结果,因此无法开始、停止和暂停;
  • Promise 无法改变已经发出的操作。

以上限制使得 Promise 在某些异步场景下变得不够灵活和有效,因此 Observable 被引入作为一种新的解决方案。

Observable 的特点和优势

Observable 是一个非常强大且灵活的异步解决方案。它的主要特点是:

  • 支持多次返回结果,具有异步集合的能力;
  • 可观察对象能够表示中间结果,并且可以开始、停止和暂停;
  • 可观察对象提供了一套强大的操作符用于转换流。

Observable 的灵活性使得它在一些较为复杂的异步场景下表现出更强的优势。例如,由于 Observable 支持暂停和继续,因此在处理用户输入之类的场景下,Observable 能够更好地掌握流的控制,不必依赖于网络请求的响应速度。同时,由于它具有多次返回结果的能力,Observable 更适合用于流媒体和游戏开发等领域,而不仅仅局限于单次请求/响应的场景。

Promise 和 Observable 的转换

在实践中,我们时常需要将 Promise 转换为 Observable 或是反过来,以适应不同的异步场景。

有时候我们需要将一个 Promise 转换成 Observable,例如在 Vue.js 中使用 axios 发送请求:

这里使用了 RxJs 中的 from 操作符,将 axios 的返回值 promise 转换成了一个可观察对象。

另外,我们也可以将 Observable 转换成 Promise:

在上述代码中,我们使用了 RxJs 中的 pipe 和 toPromise 方法将 Observable 转换成了 Promise。

Observable 的异步流程控制

在使用 Observable 进行异步编程时,我们需要掌握一些异步流程控制的方法。下面是一些常用的控制方法及其用法。

操作符 takeUntil

takeUntil 操作符可以让我们在某个条件成立时,终止一个可观察对象的执行:

-- -------------------- ---- -------
------ - -------- - ---- -------
------ - --------- - ---- -----------------

----- ------ - ---------------
----- --------- - --- --------------- -- -
  ------------- -- -
    ----------
  -- ------
---

------
  ---------------------------------
  -------------- -- ------------------

以上代码中,interval 操作符会每隔 1 秒钟产生一个数值,并将这些数值作为可观察对象。同时我们创建了一个 Promise,使得在 5 秒钟后 Promise 执行后,takeUntil 操作符就会打断该可观察对象。在此之后,就不会再产生任何数值。

操作符 debounceTime

使用 debounceTime 操作符可以让我们在指定的时间内限制可观察对象中产生的数据量,在用户输入等场景下非常实用:

-- -------------------- ---- -------
------ - --------- - ---- -------
------ - ------------ - ---- -----------------

----- ----------- - ----------------------------------
----- ------------ - ---------------------- --------
  --------------------------

-------------------------- -- -
  -------------------------------
---

以上代码中,fromEvent 操作符会在 search 元素的 input 事件上产生一个可观察对象,我们使用 debounceTime 操作符将产生的数据限制在了 1 秒钟内,以避免搜索频繁地进行请求。

结论

ES7 中引入的 Observable 作为异步解决方案,在一些较为复杂的异步场景下,相较于 Promise 具有更大的优势和潜力。在使用 Observable 时,我们需要注意异步流程控制的方法,并结合实际场景灵活运用。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/66efe85e6fbf9601973145ed

纠错
反馈