学会js中的promise,看这一篇就够了!!!

👻认识promise作用

👻promise介绍

在 JavaScript 中,Promise 是一种强大的异步编程工具,它的作用在于处理异步操作,使得代码更>具可读性和可维护性。Promise 最早出现在 ECMAScript 6(ES6)中,它为开发者提供了一种更结>构化的方式来处理异步任务,尤其是网络请求、文件读写、定时任务等等。

👻Promise 主要作用

  1. 处理异步操作:Promise 可以用来处理异步操作,例如网络请求、文件读写、定时器等等。这有助于避免回调地狱(Callback Hell)和提高代码的可读性。
  2. 更好的错误处理:Promise 允许我们轻松地捕获和处理异步操作中的错误,而不需要使用传统的 try-catch 块。
  3. 链式调用:Promise 支持链式调用,可以按顺序执行一系列的异步操作,使代码看起来更加清晰。

👻promise基本使用

Promise 是一个代表异步操作最终完成或失败的对象。一个 Promise 可以处于以下三种状态之一:

  1. Pending(进行中):初始状态,表示异步操作还在进行中,尚未完成或失败。
  2. Fulfilled(已完成):表示异步操作已成功完成。
  3. Rejected(已失败):表示异步操作发生了错误或失败。

下面是一个基本的 Promise 示例:

javascript 复制代码
const myPromise = new Promise((resolve, reject) => {
  // 异步操作,例如发送网络请求
  setTimeout(() => {
    const randomNumber = Math.random();
    if (randomNumber < 0.5) {
      resolve("成功:数据加载完成");
    } else {
      reject("失败:数据加载失败");
    }
  }, 1000);
});

myPromise.then((result) => {
  console.log(result); // 成功:数据加载完成
}).catch((error) => {
  console.error(error); // 失败:数据加载失败
});

在这个示例中,创建了一个 Promise 对象 myPromise,它模拟了一个异步操作。当异步操作完成时,调用 resolve 函数表示成功,调用 reject 函数表示失败。然后,使用 .then() 方法来处理成功的情况,使用 .catch() 方法来处理失败的情况。

👻promise的状态及状态变化

Promise 的三种状态:Pending(进行中)、Fulfilled(已成功)和Rejected(已失败)。这些状态是不可逆转的,一旦 Promise 进入了 Fulfilled 或 Rejected 状态,它将永远保持在这个状态,并且无法再次改变。

👻1. Pending(进行中)

Promise 最初的状态是 Pending,表示异步操作正在进行中,但尚未完成。在这个状态下,Promise 可以转换为 Fulfilled 或 Rejected 状态,取决于异步操作的结果。

👻2. Fulfilled(已成功)

当异步操作成功完成时,Promise 的状态将从 Pending 转换为 Fulfilled。这表示异步操作已成功,并且可以获取到结果值。

👻3. Rejected(已失败)

当异步操作由于某种原因失败时,Promise 的状态将从 Pending 转换为 Rejected。这表示异步操作已失败,并且可以获取到错误信息。

👻状态变化示例

下面是一个示例,演示了 Promise 的状态变化:

javascript 复制代码
const successPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("成功结果");
  }, 1000);
});

const failurePromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject(new Error("失败原因"));
  }, 1000);
});

successPromise
  .then((result) => 
    console.log("成功状态:", result);
  })
  .catch((error) => {
    console.error("失败状态:", error.message);
  });

failurePromise
  .then((result) => {
    console.log("成功状态:", result);
  })
  .catch((error) => {
    console.error("失败状态:", error.message);
  });

在上面的示例中,successPromise 成功完成,进入 Fulfilled 状态,并输出成功状态的结果。而 failurePromise 由于出错而进入 Rejected 状态,并输出失败状态的错误信息。

👻promise实例方法

Promise 提供了一系列实例方法,用于处理异步操作和状态变化。

👻1. then 方法

then 方法是 Promise 中最重要的方法之一,用于注册回调函数来处理异步操作的结果。它接受两个参数:onFulfilledonRejected,分别用于处理成功和失败的情况。

👻基本用法

javascript 复制代码
const myPromise = new Promise((resolve, reject) => {
  // 异步操作
  setTimeout(() => {
    resolve("数据加载完成"); // 成功时调用 resolve
    // 或者
    // reject(new Error("数据加载失败")); // 失败时调用 reject
  }, 1000);
});

myPromise
  .then((result) => {
    console.log(result); // 成功:数据加载完成
  })
  .catch((error) => {
    console.error(error.message); // 失败:数据加载失败
  });

👻多次调用 then

同一个 Promise 实例可以调用多次 then 方法,当 Promise 中的 resolve 被回调时,所有 then 方法传入的回调函数都会被调用。

javascript 复制代码
const promise = new Promise((resolve) => {
  resolve("你好");
});

// 同时调用多个 then 方法
promise.then((res) => console.log(res));
promise.then((res) => console.log(res));
promise.then((res) => console.log(res));

👻then 方法回调函数的返回值

then 方法传入的回调函数可以有返回值。如果返回的是普通值,那么这个普通值将作为一个新的 Promise 的 resolve 的值。

javascript 复制代码
const promise = new Promise((resolve) => {
  resolve("你好");
});

promise.then(() => "then").then((res) => console.log(res)); // 打印 "then"

如果返回的是 Promise,那么就可以再次调用 then 方法。

javascript 复制代码
const promise = new Promise((resolve) => {
  resolve("你好");
});

promise
  .then(() => {
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve("success");
      }, 2000);
    });
  })
  .then((msg) => {
    // 2 秒后打印 "success"
    console.log(msg);
  });

如果返回的是一个对象,并且该对象实现了 thenable,该 then 函数有两个参数 resolvereject,则 resolve 的值将会传递给下一个 Promise。

javascript 复制代码
const promise = new Promise((resolve) => {
  resolve("你好");
});

promise
  .then(() => {
    return {
      then(resolve) {
        return resolve("success");
      },
    };
  })
  .then((msg) => {
    // 打印 "success"
    console.log(msg);
  });

👻2. catch 方法

除了通过 then 方法的第二个参数来捕获 reject 错误之外,还可以使用 catch 方法,它返回一个新的 Promise,用于处理 Promise 实例的错误。

javascript 复制代码
const promise = new Promise((resolve, reject) => {
  reject("error");
});

// 使用 catch 捕获错误
promise.catch((err) => {
  console.error(err); // 打印 "error"
});

// 或者
promise
  .then(() => {})
  .catch((err) => {
    console.error(err); // 打印 "error"
  });

catch 方法也可以多次调用,只要 Promise 实例的状态为 rejected,那么就会调用 catch 方法。

javascript 复制代码
const promise = new Promise((resolve, reject) => {
  reject("error");
});

// 这两个 catch 都会调用
promise.catch((err) => {
  console.log(err);
});
promise.catch((err) => {
  console.log(err);
});

👻3. finally 方法

finally 方法是 ES9(ES2018) 新增的特性,无论一个 Promise 实例是 fulfilled 还是 rejectedfinally 都会执行。它不接收任何参数。

javascript 复制代码
const promise = new Promise((resolve, reject) => {
  reject("error");
});

promise
  .then((res) => {
    console.log("res:", res);
  })
  .catch((err) => {
    console.log("err", err);
  })
  .finally(() => {
    console.log("finally code execute");
  });

finally 方法适用于需要在不管 Promise 状态如何都要执行一些清理操作的场景。

👻promise的类方法

除了 Promise 实例方法,Promise 还提供了一些类方法,用于创建和处理多个 Promise 实例。

👻1. Promise.resolve()

Promise.resolve() 方法返回一个以给定值解析后的 Promise 对象。如果该值是一个 Promise,它将被返回原封不动(不进行解析)。

javascript 复制代码
const resolvedPromise = Promise.resolve("解析成功");
const rejectedPromise = Promise.reject("解析失败");

resolvedPromise.then((result) => {
  console.log(result); // 解析成功
});

rejectedPromise.catch((error) => {
  console.error(error); // 解析失败
});

// 处理 Promise 实例
const originalPromise = new Promise((resolve) => {
  resolve("原始 Promise");
});

const resolvedWithPromise = Promise.resolve(originalPromise);

resolvedWithPromise.then((result) => {
  console.log(result); // 原始 Promise
});

👻2. Promise.reject()

Promise.reject() 方法返回一个带有拒绝原因的 Promise 对象。

javascript 复制代码
const rejectedPromise = Promise.reject("拒绝原因");

rejectedPromise.catch((error) => {
  console.error(error); // 拒绝原因
});

👻3. Promise.all()

Promise.all() 方法接受一个可迭代的对象,如数组或字符串,里面包含多个 Promise 对象,并返回一个新的 Promise 对象。这个新的 Promise 在所有输入的 Promise 都成功解析后才会解析,如果任何一个 Promise 被拒绝,它就会立即被拒绝。

javascript 复制代码
const promise1 = Promise.resolve("第一个 Promise");
const promise2 = Promise.resolve("第二个 Promise");
const promise3 = Promise.reject("第三个 Promise");

Promise.all([promise1, promise2])
  .then((results) => {
    console.log(results); // ["第一个 Promise", "第二个 Promise"]
  })
  .catch((error) => {
    console.error(error);
  });

Promise.all([promise1, promise2, promise3])
  .then((results) => {
    console.log(results); // 这里不会执行,会立即被拒绝
  })
  .catch((error) => {
    console.error(error); // 第三个 Promise 拒绝的原因
  });

👻4. Promise.race()

Promise.race() 方法接受一个可迭代的对象,如数组或字符串,里面包含多个 Promise 对象,并返回一个新的 Promise 对象。这个新的 Promise 在第一个输入的 Promise 成功解析或拒绝后立即解析或拒绝。

javascript 复制代码
const promise1 = new Promise((resolve) => {
  setTimeout(() => {
    resolve("第一个 Promise");
  }, 1000);
});

const promise2 = new Promise((resolve) => {
  setTimeout(() => {
    resolve("第二个 Promise");
  }, 500);
});

Promise.race([promise1, promise2])
  .then((result) => {
    console.log(result); // 第二个 Promise(因为它解析得更快)
  })
  .catch((error) => {
    console.error(error);
  });

👻Promise 链的执行

在 JavaScript 中,Promise 链是一种处理多个异步操作的方法,其中一个操作的结果将传递给下一个操作。这种方法使得异步操作能够按照预期的顺序执行,提高了代码的可读性和可维护性。

👻创建 Promise 链

Promise 链是通过在 then 方法中返回新的 Promise 来创建的。每次调用 then 方法都会返回一个新的 Promise,它可以用来定义下一个操作。

javascript 复制代码
const initialPromise = someAsyncOperation();

initialPromise
  .then((result) => {
    // 第一个异步操作的结果
    return anotherAsyncOperation(result); // 返回新的 Promise
  })
  .then((result) => {
    // 第二个异步操作的结果
    return yetAnotherAsyncOperation(result); // 返回新的 Promise
  })
  .then((finalResult) => {
    // 最终的结果
    console.log("最终结果:", finalResult);
  })
  .catch((error) => {
    // 处理任何错误
    console.error("错误:", error);
  });

在上面的示例中,initialPromise 是一个异步操作的 Promise。我们通过 then 方法创建了一个 Promise 链。在每个 then 中,我们可以访问前一个操作的结果,并返回一个新的 Promise 来定义下一个操作。最后,使用 catch 方法来处理任何可能的错误。

👻Promise 链的执行顺序

Promise 链中的操作是按照顺序执行的,每个操作都在前一个操作成功完成后才会触发。这确保了异步操作的顺序性。

如果某个操作返回一个普通的值而不是 Promise,它将被包装成一个立即成功的 Promise,并立即传递给下一个操作。

javascript 复制代码
const promiseChain = Promise.resolve(1)
  .then((result) => {
    console.log("第一步:", result);
    return result + 1; // 返回一个新的值
  })
  .then((result) => {
    console.log("第二步:", result);
    return result * 2; // 返回一个新的值
  })
  .then((result) => {
    console.log("第三步:", result);
    throw new Error("出错了"); // 抛出一个错误
  })
  .catch((error) => {
    console.error("捕获到错误:", error.message);
  });

// 输出:
// 第一步: 1
// 第二步: 2
// 第三步: 4
// 捕获到错误: 出错了

👻异步操作的顺序性

Promise 链的执行顺序确保了异步操作的顺序性,即使异步操作本身具有不同的执行时间。

javascript 复制代码
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

delay(1000)
  .then(() => {
    console.log("第一步完成");
    return delay(2000); // 2 秒延迟
  })
  .then(() => {
    console.log("第二步完成");
    return delay(500); // 0.5 秒延迟
  })
  .then(() => {
    console.log("第三步完成");
  });

// 输出:
// 第一步完成
// 第二步完成
// 第三步完成

在上面的示例中,尽管每个 delay 函数具有不同的延迟时间,但它们仍然按照顺序执行。

👻Promise 链中的错误处理

如果任何一个异步操作失败(Promise 进入 Rejected 状态),错误会传递给最近.catch() 方法进行处理。例如:

javascript 复制代码
asyncOperation1()
  .then((result1) => {
    console.log(result1); // 操作 1 完成
    return asyncOperation2(); // 返回第二个异步操作的 Promise
  })
  .then((result2) => {
    console.log(result2); // 操作 2 完成
    throw new Error("操作 3 失败"); // 手动抛出错误
  })
  .then((result3) => {
    console.log(result3); // 不会执行到这里
  })
  .catch((error) => {
    console.error("出错了:", error); // 出错了: Error: 操作 3 失败
  });

在上面的示例中,第二个 .then() 方法手动抛出了一个错误,因此会触发 .catch() 方法来处理错误。

相关推荐
Martin -Tang3 分钟前
vite和webpack的区别
前端·webpack·node.js·vite
迷途小码农零零发4 分钟前
解锁微前端的优秀库
前端
王解1 小时前
webpack loader全解析,从入门到精通(10)
前端·webpack·node.js
老码沉思录1 小时前
写给初学者的React Native 全栈开发实战班
javascript·react native·react.js
我不当帕鲁谁当帕鲁1 小时前
arcgis for js实现FeatureLayer图层弹窗展示所有field字段
前端·javascript·arcgis
那一抹阳光多灿烂1 小时前
工程化实战内功修炼测试题
前端·javascript
放逐者-保持本心,方可放逐2 小时前
微信小程序=》基础=》常见问题=》性能总结
前端·微信小程序·小程序·前端框架
毋若成4 小时前
前端三大组件之CSS,三大选择器,游戏网页仿写
前端·css
红中马喽4 小时前
JS学习日记(webAPI—DOM)
开发语言·前端·javascript·笔记·vscode·学习
Black蜡笔小新5 小时前
网页直播/点播播放器EasyPlayer.js播放器OffscreenCanvas这个特性是否需要特殊的环境和硬件支持
前端·javascript·html