ES6指的是ECMAScript 6,也被称为ES2015。它是JavaScript的一种版本,是ECMAScript标准的第六个版本,于2015年发布。ECMAScript是JavaScript的规范,定义了语言的核心特性和行为。ES6引入了许多新的语法特性和功能,以使JavaScript代码更加现代化、清晰和强大。 在此专栏中,我们会持续更新有关于ES6的新特性,感兴趣的小伙伴们可以订阅一下~
前言
在上篇文章中我们讲了JS中异步
,异步有好处也有坏处,我们讲了用回调函数
来处理异步,但是使用回调函数方法会造成回调地狱
,这种结构会使代码难以维护,容易出现错误,并且不符合良好的代码风格。今天我们来聊聊Promise
,这是处理异步的一种优雅的方式,它同时也是ES6新增的一个对象。
Promise
Promise 是 JavaScript 中用于处理异步操作的对象,它代表了一个异步操作的最终完成或失败,并返回相应的结果。Promise 的主要目标是提供一种更优雅和灵活的方式来处理异步代码,避免回调地狱,使异步代码更易读、更易维护。
一个 Promise 可以处于以下三种状态之一:
- Pending(进行中): 初始状态,异步操作还在进行中。
- Fulfilled(已成功): 异步操作成功完成,返回了一个值。
- Rejected(已失败): 异步操作失败,抛出一个错误。
创建promise对象
创建 Promise 对象时,Promise 构造函数接受一个带有 resolve
和 reject
两个参数的函数作为参数。这个函数会在 Promise 对象的状态发生改变时执行。这个函数通常包含异步操作,当异步操作成功时,调用 resolve
,将 Promise 置为 Fulfilled 状态,传递异步操作的结果;当异步操作失败时,调用 reject
,将 Promise 置为 Rejected 状态,传递错误信息。
const promise = new Promise((resolve, reject) => { // 异步操作代码 if (/* 操作成功 */) { resolve(result); // 将 Promise 置为 Fulfilled 状态,并传递结果 } else { reject(error); // 将 Promise 置为 Rejected 状态,并传递错误信息 } });
在这个代码中,resolve
和 reject
是由 JavaScript 引擎提供的两个函数。当异步操作成功时,调用 resolve
,传递异步操作的结果;当异步操作失败时,调用 reject
,传递错误信息。
我们举一个一个简单的例子:
const promise = new Promise((resolve, reject) => { // 模拟异步操作,比如一个网络请求 setTimeout(() => { const success = Math.random() > 0.5; // 模拟异步操作成功或失败 if (success) { resolve("Operation successful!"); // 异步操作成功,调用 resolve } else { reject("Operation failed!"); // 异步操作失败,调用 reject } }, 1000); });
在这个例子中,promise
是一个 Promise 对象,它包含了一个模拟的异步操作。在这个异步操作中,如果 Math.random()
生成的随机数大于 0.5,则认为操作成功,调用 resolve
,否则认为操作失败,调用 reject
。
Promise处理异步
Promise 实例具有 then
方法,该方法接受两个回调函数作为参数,分别用于处理异步操作成功和失败的情况。可以链式调用多个 then
方法,这样可以更清晰地表达多个异步操作的顺序。
下面是一个简单的 Promise 链式调用的例子,假设有三个异步函数 asyncFunction1
、asyncFunction2
、asyncFunction3
,它们分别返回 Promise 对象。这些函数在链式调用中依次执行:
function asyncFunction1() { return new Promise((resolve, reject) => { setTimeout(() => { console.log("Async Function 1"); resolve("Result from Async Function 1"); }, 1000); }); } function asyncFunction2(data) { return new Promise((resolve, reject) => { setTimeout(() => { console.log("Async Function 2 with data:", data); resolve("Result from Async Function 2"); }, 1000); }); } function asyncFunction3(data) { return new Promise((resolve, reject) => { setTimeout(() => { console.log("Async Function 3 with data:", data); resolve("Result from Async Function 3"); }, 1000); }); } // 链式调用 asyncFunction1() .then(result1 => asyncFunction2(result1)) .then(result2 => asyncFunction3(result2)) .then(finalResult => { console.log("Final Result:", finalResult); })
我们先一起来看看输出结果:
在这个例子中,asyncFunction1
、asyncFunction2
、asyncFunction3
会依次执行,每个函数返回的 Promise 对象通过 then
方法连接起来,形成一个 Promise 链。每个 then
方法中的回调函数会接收上一个 Promise 的成功结果,并返回一个新的 Promise。
整个链式调用的执行顺序是:
asyncFunction1
执行,1 秒后成功,输出 "Async Function 1";then(result1 => asyncFunction2(result1))
中的回调函数接收到asyncFunction1
的成功结果,调用asyncFunction2
,1 秒后成功,输出 "Async Function 2 with data: Result from Async Function 1";then(result2 => asyncFunction3(result2))
中的回调函数接收到asyncFunction2
的成功结果,调用asyncFunction3
,1 秒后成功,输出 "Async Function 3 with data: Result from Async Function 2";then(finalResult => { console.log("Final Result:", finalResult); })
中的回调函数接收到asyncFunction3
的成功结果,输出 "Final Result: Result from Async Function 3"。
通过这种方式,Promise 链使得异步操作的顺序和逻辑更加清晰和可读。