📜  与延迟相反 - Javascript (1)

📅  最后修改于: 2023-12-03 15:06:13.660000             🧑  作者: Mango

与延迟相反 - JavaScript

在编写 Web 应用时,经常需要通过异步编程实现数据获取和操作,而 JavaScript 提供了多种处理异步操作的方式。其中,最常用的方式是使用回调函数,但这种方式可能会导致代码复杂度和可读性下降,同时还会面临多个回调函数嵌套的问题(也称为“回调地狱”)。

为了解决这些问题,JavaScript 社区开发了一种新的编程模型,称为 Promise。Promise 是一种封装异步操作的对象,可以避免回调地狱的问题,提高代码的可读性和可维护性。本文将介绍 Promise 的基本用法和特性,以帮助您更好地理解和应用 Promise。

什么是 Promise?

Promise(承诺)是一个对象,它代表了某个异步操作的最终完成(或失败)状态以及其返回的值。Promise 有三种状态:未完成(pending)、已完成(fulfilled)和已失败(rejected)。当一个 Promise 对象被创建时,它的状态为 pending。

// 创建一个 Promise 对象
const promise = new Promise((resolve, reject) => {
  // 异步操作
  setTimeout(() => {
    // 成功时调用 resolve 函数并传递结果值
    resolve('Hello, World!');
    // 失败时调用 reject 函数并传递错误信息
    // reject(new Error('Something went wrong!'));
  }, 1000);
});

Promise 对象需要传递一个函数作为参数,该函数又称为“执行器”(executor)。执行器内部执行异步操作,并在操作完成后调用 resolve 函数来改变 Promise 的状态为 fulfilled,或者调用 reject 函数来改变 Promise 的状态为 rejected。

在创建完 Promise 后,可以通过 then 或 catch 方法注册回调函数来处理 Promise 对象的状态变化。then 方法接收两个函数作为参数,分别对应 Promise 对象状态为 fulfilled 或 rejected 时的回调函数。catch 方法接收一个回调函数,用于处理 Promise 对象状态为 rejected 时的情况。

// 处理 Promise 对象状态变化
promise
  .then(result => console.log(result)) // 执行操作成功时的回调函数
  .catch(error => console.error(error)); // 执行操作失败时的回调函数
Promise 的链式调用

Promise 对象的 then 方法可以返回一个新的 Promise 对象,从而实现链式调用的效果。例如,当一个 Promise 对象表示的异步操作完成后,需要再执行另一个异步操作,可以通过链式调用的方式实现。

// 异步操作 1
const promise1 = new Promise(resolve => {
  setTimeout(() => {
    resolve('Promise 1 resolved');
  }, 1000);
});

// 异步操作 2
const promise2 = new Promise(resolve => {
  setTimeout(() => {
    resolve('Promise 2 resolved');
  }, 1000);
});

// 链式调用
promise1
  .then(result1 => {
    console.log(result1);
    return promise2;
  })
  .then(result2 => console.log(result2));

在上面的例子中,promise1 对象代表了一个异步操作,promise2 对象代表了另一个异步操作。通过调用 promise1 的 then 方法,可以在 promise1 异步操作完成时执行一个回调函数,并将它的结果传递给下一个 then 方法。在第一个 then 方法内部返回 promise2 对象,从而实现了异步操作的链式调用。

Promise 的其他特性

除了基本特性以外,Promise 还提供了一些其他的功能,如 Promise.all、Promise.race 和 Promise.resolve。

  1. Promise.all

Promise.all 方法接收一个 Promise 对象数组作为参数,并返回一个新的 Promise 对象。当所有的 Promise 对象都变为 fulfilled 状态时,返回的 Promise 对象状态为 fulfilled,并将所有 Promise 对象的结果作为一个数组返回。当其中任意一个 Promise 对象变为 rejected 状态时,返回的 Promise 对象状态为 rejected,并将第一个 Promise 对象的错误信息作为错误信息返回。

// Promise.all 方法
const promises = [
  Promise.resolve(1),
  Promise.resolve(2),
  Promise.resolve(3),
];

Promise.all(promises).then(results => console.log(results)); // [1, 2, 3]
  1. Promise.race

Promise.race 方法接收一个 Promise 对象数组作为参数,并返回一个新的 Promise 对象。当其中任意一个 Promise 对象变为 fulfilled 或 rejected 状态时,返回的 Promise 对象状态和结果与第一个变为 fulfilled 或 rejected 状态的 Promise 对象保持一致。

// Promise.race 方法
const promises = [
  new Promise(resolve => setTimeout(() => resolve(1), 1000)), // 1 秒后返回
  new Promise(resolve => setTimeout(() => resolve(2), 2000)), // 2 秒后返回
  new Promise(resolve => setTimeout(() => resolve(3), 3000)), // 3 秒后返回
];

Promise.race(promises).then(result => console.log(result)); // 1
  1. Promise.resolve

Promise.resolve 方法接收一个参数,并返回一个 Promise 对象。如果该参数是一个 Promise 对象,返回该对象。否则,返回一个新的 Promise 对象,状态为 fulfilled,并将该参数作为结果返回。

// Promise.resolve 方法
Promise.resolve(42).then(result => console.log(result)); // 42
Promise.resolve(new Error('Something went wrong!')).catch(error => console.error(error));
总结

Promise 是一种封装异步操作的对象,可以避免回调地狱的问题,提高代码的可读性和可维护性。Promise 有三种状态:未完成、已完成和已失败。可以使用 then 和 catch 方法注册回调函数来处理 Promise 对象的状态变化。Promise 对象的 then 方法可以返回一个新的 Promise 对象,从而实现链式调用的效果。Promise 还提供了一些其他的功能,如 Promise.all、Promise.race 和 Promise.resolve。