前言
本片文章博主主要从介绍promise->用法->手写实现->常用API->特性->适用场景六个方面给大家展开讲解
感兴趣的不妨看下去吧 记得三联支持作者
介绍
Promise是JavaScript中用于处理异步操作的一种机制。它解决了传统回调函数嵌套(callback hell)带来的可读性差、错误处理困难等问题,使得异步代码更加清晰、可维护。
一个Promise代表了一个异步操作的最终完成或失败,并且可以返回一个值。它有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。一旦Promise的状态变为fulfilled或rejected,就称为“settled”(已定型)。
在以往我们如果处理多层异步操作,我们往往会像下面那样编写我们的代码
doSomething(function(result) { doSomethingElse(result, function(newResult) { doThirdThing(newResult, function(finalResult) { console.log('得到最终结果: ' + finalResult); }, failureCallback); }, failureCallback); }, failureCallback);
阅读上面代码,是不是很难受,上述形成了经典的回调地狱
现在通过Promise的改写上面的代码
doSomething().then(function(result) { return doSomethingElse(result); }) .then(function(newResult) { return doThirdThing(newResult); }) .then(function(finalResult) { console.log('得到最终结果: ' + finalResult); }) .catch(failureCallback);
瞬间感受到promise解决异步操作的优点:
- 链式操作减低了编码难度
- 代码可读性明显增强
下面我们正式来认识promise:
状态
promise对象仅有三种状态
- pending(进行中)
- fulfilled(已成功)
- rejected(已失败)
特点 - 对象的状态不受外界影响,只有异步操作的结果,可以决定当前是哪一种状态
- 一旦状态改变(从pending变为fulfilled和从pending变为rejected),就不会再变,任何时候都可以得到这个结果
流程
认真阅读下图,我们能够轻松了解promise整个流程
用法
Promise对象是一个构造函数,用来生成Promise实例
const promise = new Promise(function(resolve, reject) {});
Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject
- resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”
- reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”
手写实现一个promise
class MyPromise { constructor(executor) { this.status = 'pending'; // Promise的状态,初始为pending this.value = undefined; // Promise的值,默认为undefined this.callbacks = []; // 存储then回调函数的数组 const resolve = (value) => { if (this.status === 'pending') { this.status = 'fulfilled'; // 改变Promise的状态为fulfilled this.value = value; // 设置Promise的值 // 依次执行then回调函数 this.callbacks.forEach((callback) => { callback.onFulfilled(value); }); } }; const reject = (reason) => { if (this.status === 'pending') { this.status = 'rejected'; // 改变Promise的状态为rejected this.value = reason; // 设置Promise的值 // 依次执行then回调函数 this.callbacks.forEach((callback) => { callback.onRejected(reason); }); } }; try { executor(resolve, reject); // 执行executor函数,并传入resolve和reject作为参数 } catch (error) { reject(error); // 如果executor执行出错,则将错误信息传递给reject } } then(onFulfilled, onRejected) { return new MyPromise((resolve, reject) => { const handleCallback = (callback) => { try { const result = callback(this.value); // 执行回调函数,并传入Promise的值 if (result instanceof MyPromise) { result.then(resolve, reject); // 如果回调函数返回的是一个Promise,使用then继续处理 } else { resolve(result); // 否则将回调函数的返回值作为新Promise的值 } } catch (error) { reject(error); // 如果回调函数执行出错,则将错误信息传递给reject } }; if (this.status === 'pending') { this.callbacks.push({ onFulfilled: (value) => handleCallback(onFulfilled), onRejected: (reason) => handleCallback(onRejected) }); } else if (this.status === 'fulfilled') { handleCallback(onFulfilled); } else if (this.status === 'rejected') { handleCallback(onRejected); } }); } catch(onRejected) { return this.then(null, onRejected); // catch方法实际上是then方法的语法糖,只接受onRejected回调 } static resolve(value) { return new MyPromise((resolve) => resolve(value)); // 创建一个状态为fulfilled的Promise,并将指定的值传递给resolve } static reject(reason) { return new MyPromise((resolve, reject) => reject(reason)); // 创建一个状态为rejected的Promise,并将指定的原因传递给reject } static all(promises) { return new MyPromise((resolve, reject) => { const results = []; // 存储每个Promise的结果 let count = 0; // 记录已完成的Promise数量 promises.forEach((promise, index) => { promise.then((value) => { results[index] = value; count++; if (count === promises.length) { resolve(results); // 所有Promise都完成时,将结果传递给resolve } }, reject); }); }); } static race(promises) { return new MyPromise((resolve, reject) => { promises.forEach((promise) => { promise.then(resolve, reject); // 只要有一个Promise完成或拒绝,就将结果传递给resolve或reject }); }); } }
常用API
- then(onFulfilled, onRejected):then方法用于注册回调函数,在Promise状态发生改变时执行相应的回调函数。onFulfilled用于处理Promise状态变为fulfilled时的情况,onRejected用于处理Promise状态变为rejected时的情况。then方法返回一个新的Promise。
- catch(onRejected):catch方法是then方法的语法糖,只接受onRejected回调函数,用于处理Promise状态变为rejected时的情况。catch方法返回一个新的Promise。
- Promise.resolve(value):静态方法resolve用于创建一个状态为fulfilled的Promise,并将指定的值传递给resolve。
- Promise.reject(reason):静态方法reject用于创建一个状态为rejected的Promise,并将指定的原因传递给reject。
- Promise.all(promises):静态方法all接收一个包含多个Promise的数组,返回一个新的Promise。当所有Promise都变为fulfilled时,新的Promise变为fulfilled,并将每个Promise的值按顺序传递给resolve;如果有任何一个Promise变为rejected,新的Promise将变为rejected,并将第一个被reject的Promise的原因传递给reject。
- Promise.race(promises):静态方法race接收一个包含多个Promise的数组,返回一个新的Promise。只要有一个Promise变为fulfilled或rejected,新的Promise就会变为相应的状态,并将第一个完成的Promise的结果传递给resolve或reject。
特性
- 异步操作管理:Promise是用于处理异步操作的一种机制。它可以将异步任务封装为一个Promise对象,使得异步任务的执行和结果可以更加可控和可预测。
- 状态管理:Promise具有三种状态:pending(进行中)、fulfilled(已完成)和rejected(已拒绝)。初始状态为pending,当异步操作成功完成时状态变为fulfilled,若发生错误则状态变为rejected。状态一旦改变,就不可再变。
- 链式调用:Promise通过then方法支持链式调用。then方法接收两个参数:onFulfilled(当Promise状态变为fulfilled时调用的回调函数)和onRejected(当Promise状态变为rejected时调用的回调函数)。每次调用then方法后都会返回一个新的Promise对象,因此可以连续调用多个then方法形成链式操作。
- 值传递:Promise可以将值在异步操作之间传递。当一个Promise状态变为fulfilled时,可以将其值传递给下一个Promise或者通过回调函数返回给调用方。
- 错误处理:Promise具有错误传递和捕获的能力。在Promise链中,任何一个Promise出现异常都会触发onRejected回调函数,并将异常信息传递到catch方法或后续的错误处理函数中。
- 多个Promise的协同处理:Promise提供了静态方法如Promise.all和Promise.race,用于处理多个Promise的协同处理情况。Promise.all可以等待多个Promise都成功完成后再执行后续操作,而Promise.race会在第一个完成的Promise上触发后续操作。
适用场景
- 异步操作:Promise可用于处理异步操作,使代码更易读、维护和扩展。通过then方法链式调用,可以按顺序执行一系列异步操作。
- AJAX 请求:使用Promise可以更优雅地处理AJAX请求,通过将AJAX封装成Promise,可以在请求成功或失败后执行相应的回调函数。
- 并发控制:Promise.all方法可以用于并发控制,当多个异步任务都完成时再进行下一步操作。
- 错误处理:Promise的特性之一是错误捕获和传递。通过catch方法可以统一处理Promise链中的错误,提高代码的可读性和错误管理能力。
后言
创作不易 如果该文章对您有帮助 不妨三联支持一下作者 感谢
下一期会出 promise的链式调用和promise的嵌套的实现
如果感兴趣下次来看