发布于 2026-01-06 2 阅读
0

JavaScript Promises vs Observables DEV's Worldwide Show and Tell Challenge Presented by Mux: Pitch Your Projects!

JavaScript Promise 与 Observables

由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!

JavaScript 中的异步编程
JavaScript 中有多种方法可以创建异步代码。其中最重要的几种如下:

  • 回调函数
  • 承诺
  • 异步/等待
  • RxJS Observables

回调函数
是传统的异步编程方法。你将一个函数作为参数传递给另一个执行异步任务的函数。当异步任务完成后,执行异步任务的函数会调用你的回调函数。
这种方法的主要缺点在于当存在多个链式异步任务时,你需要嵌套定义回调函数,层层嵌套,这就是所谓的“回调地狱”

function greeting(name) {
  console.log(`Hello ${name}!`);
}

function introduction(firstName, lastName, callback) {
  const fullName = `${firstName} ${lastName}`;

  callback(fullName);
}

introduction('Nouman','shah', greeting); 
//"Hello Nouman shah!"
Enter fullscreen mode Exit fullscreen mode

Promise
是在 ES6 (2015) 中引入的,目的是编写比回调函数更易读的异步代码。
回调函数和 Promise 的主要区别在于,回调函数需要你告诉执行函数在异步任务完成后应该做什么,而 Promise 则是执行函数返回一个特殊对象(Promise),然后你再告诉 Promise 在异步任务完成后应该做什么。Promise
有三种状态:

  • 待处理:这是操作开始之前 Promise 的初始状态
  • 已完成:这意味着指定的操作已完成。
  • 操作失败:操作未完成;通常会抛出错误值。
function getUsers(onSuccess) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      // Handle resolve and reject in the asynchronous API
      if (onSuccess) {
        resolve([
          {id: 1, name: 'Jerry'},
          {id: 2, name: 'Elaine'},
          {id: 3, name: 'George'},
        ])
      } else {
         reject('Failed to fetch data!')
      }
    }, 1000)
  })
}

// Run the getUsers function with the false flag to trigger an error
getUsers(false)
  .then((response) => {
    console.log(response)
  })
  .catch((error) => {
    console.log(error)
  })
Enter fullscreen mode Exit fullscreen mode

异步/等待:
有一种特殊的语法可以更方便地处理 Promise,叫做“异步/等待”。它出乎意料地容易理解和使用。

基本上,你可以将一个函数声明为异步函数,这样就可以在该函数体中使用 `await` 关键字。`await` 关键字可以放在一个求值为 Promise 的表达式前面。`await` 关键字会暂停异步函数的执行,直到 Promise 被解析。当 Promise 被解析时,整个 `await` 表达式的值会变为 Promise 的结果值,然后异步函数的执行才会恢复。
此外,异步函数本身也会返回一个 Promise,该 Promise 会在函数体执行完毕后被解析。

function asyncTask(i) {
    return new Promise(resolve => resolve(i + 1));
}
async function runAsyncTasks() {
    const res1 = await asyncTask(0);
    const res2 = await asyncTask(res1);
    const res3 = await asyncTask(res2);
    return "Everything done"
}
runAsyncTasks().then(result => console.log(result));
Enter fullscreen mode Exit fullscreen mode

RxJS Observables
类似于回调函数和 Promise,负责处理异步请求。Observables 是 RxJS 库的一部分,该库利用 Observables 的特性,使编写异步代码变得非常容易。

可观测物理量会经历四个阶段。它们分别是:

  • 创建
  • 订阅
  • 执行
  • 毁灭

可观察对象的创建是通过 create 函数完成的。

var observable = Rx.Observable.create((observer: any) =>{
})
Enter fullscreen mode Exit fullscreen mode

要让一个可观察对象生效,我们需要订阅它。这可以通过 subscribe 方法来实现。

observable.subscribe((data)=>{
   console.log(data);    
})
Enter fullscreen mode Exit fullscreen mode

创建代码块内部执行的是可观察对象的操作。

在发生错误或收到完整通知后,可观察对象会被销毁,并自动取消订阅。但在某些情况下,我们需要手动取消订阅。要手动执行此操作,只需使用:

var subscription = observable.subscribe(x => console.log(x)); // Later: subscription.unsubscribe();
Enter fullscreen mode Exit fullscreen mode

承诺与可观察值

可观察对象是惰性的,而承诺则不是。

  • Promise 具有“急切”特性:一旦创建 Promise,执行器函数就会立即被调用。
  • 可观察对象是惰性的:只有当客户端订阅可观察对象时,才会调用订阅者函数。

与 Promise 不同,Observable 可以处理多个值。Promise
只能提供一个值,而 Observable 可以提供多个值。

可观察对象是可以取消的。
你可以使用 unsubscribe 方法取消订阅来取消可观察对象,而 Promise 则没有这样的功能。

文章来源:https://dev.to/nomishah/javascript-promises-vs-observables-fpn