什么是 Promise
Promise 是一种处理异步操作的方式,可以优雅地避免了回调地狱(Callback Hell)。
在 JavaScript 中,经常需要处理异步操作,例如读取文件、发送网络请求或者执行定时器等。这些操作需要时间来完成,而时间不是可控的,因此我们需要使用回调函数来告诉 JavaScript 引擎,在异步操作完成后要执行哪些代码。
但是,在处理多个异步操作时,回调函数嵌套会造成代码可读性差,维护性差,导致代码可读性降低,维护性变得非常困难。因此,Promise 就应运而生,它是一种更加优雅的处理异步操作的方式。
Promise 原理
Promise 最重要的部分是一个状态机(State Machine),它有三种状态:
- pending:等待状态,既不是成功也不是失败。
- fulfilled:操作成功的状态。
- rejected:操作失败的状态。
Promise 的流程如下:
- 创建 Promise 对象;
- 将异步操作交给 Promise 对象;
- Promise 对象返回一个 Promise 实例;
- Promise 管理异步操作;
- 异步操作完成,通过 Promise 实例的 resolve() 方法通知 Promise 对象;
- 如果异步操作成功,Promise 对象就会从 pending 状态变成 fulfilled 状态,然后执行 then() 方法中的回调函数;
- 如果异步操作失败,Promise 对象就会从 pending 状态变成 rejected 状态,然后执行 catch() 方法中的回调函数。
实现 Promise
下面使用 ES6 来实现一个 Promise。
// javascriptcn.com 代码示例 class MyPromise { constructor(fn) { this.state = "pending"; // 初始化状态为 pending this.value = undefined; // 初始化值为 undefined this.successCB = []; // 成功的回调函数 this.failCB = []; // 失败的回调函数 const resolve = (value) => { if (this.state === "pending") { this.state = "fulfilled"; this.value = value; this.successCB.forEach((fn) => fn(this.value)); } }; const reject = (value) => { if (this.state === "pending") { this.state = "rejected"; this.value = value; this.failCB.forEach((fn) => fn(this.value)); } }; try { fn(resolve, reject); // 执行异步操作 } catch (error) { reject(error); } } then(fn) { if (this.state === "fulfilled") { fn(this.value); } else { this.successCB.push(fn); } return this; // 返回 this,实现可链式调用 } catch(fn) { if (this.state === "rejected") { fn(this.value); } else { this.failCB.push(fn); } return this; // 返回 this,实现可链式调用 } }
示例代码
下面使用示例代码来演示如何使用我们实现的 MyPromise。
// javascriptcn.com 代码示例 const promise = new MyPromise((resolve, reject) => { setTimeout(() => { const num = Math.random(); if (num > 0.5) { resolve("成功"); } else { reject("失败"); } }, 1000); }); promise .then((res) => console.log(res)) .catch((err) => console.log(err));
通过调用 MyPromise 的 then() 方法可以设置成功时的回调函数,catch() 方法可以设置失败时的回调函数。
在这个示例中,我们使用了 setTimeout() 来模拟一个异步操作。当 num 大于 0.5 时,Promise 对象返回成功,否则返回失败。
最终将在 then() 方法或者 catch() 方法中输出结果。
总结
通过本文的介绍,我们了解了 Promise 的实现原理,并使用 ES6 来实现了一个 MyPromise。同时,提供了示例代码来演示如何使用 MyPromise,并说明了可链式调用的实现方式。
因此,掌握 Promise 对于开发者来说是很重要的,它可以让代码变得更加优雅,更加可读,也更加易于维护。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/654b615f7d4982a6eb53dabc