ES6 Promise 生命周期解析与创建使用指南
本文深入解析ES6中Promise的概念、生命周期及创建方法。详细阐述Pending、Fulfilled和Rejected三种状态,通过Node.js读取文件示例演示如何构建Promise及处理异步结果,并对比then与catch方法的适用场景,帮助开发者掌握异步编程的核心技巧。
Promise的概念与生命周期
一:Promise的概念
Promise在中文里意为“承诺”,指代当前未发生但未来必定出现的事件。在编程语境下,Promise是异步操作结果的占位符。开发者无需关注异步结果何时返回,只需定义结果产生时的处理逻辑即可。
二:Promise的生命周期
异步事件并非立即执行代码,其结果可能在操作完成后一段时间才返回,因此存在生命周期。例如使用电饭煲煮饭,从【放入米并开始计时】到【计时结束】,这一过程构成了煮饭的生命周期。 一个 Promise 的生命周期主要包含 2 个阶段:
Promise的生命周期主要包含两个阶段: 1: unsettled(pending)处理中 -> 对应米饭从定时开始到结束的过程 2: settled (fulfilled或者rejected) 处理完成 -> 对应定时结束后的最终状态
在settled阶段,Promise可能处于fulfilled或rejected两种状态之一,具体含义如下:
1: fulfilled Promise操作成功完成 -> 类比煮饭时水米比例适宜,米饭煮熟 2: rejected Promise操作失败 -> 类比煮饭时水量不足,导致米饭夹生
Promise内部通过PromiseState属性记录三种状态:pending、fulfilled和rejected。尽管这些状态无法直接读取,但可通过Promise提供的接口方法来编写相应的处理程序,后续将详细介绍。
创建Promise的方法
三:如何创建一个Promise
通过煮饭的类比,相信您对Promise的概念和生命周期已有一定理解。接下来,我们将探讨如何实际创建一个Promise(即如何煮饭)。
声明:由于Promise分为未完成和已完成两种类型,本文仅讨论未完成的Promise。已完成的Promise将在后续章节介绍,目前无需关注。
使用Promise构造函数可以创建Promise实例。该构造函数接收一个参数:一个函数,称为执行器(executor)函数。您可以将其类比为煮饭所用的电饭煲。
执行器(executor)函数也是一个函数,因此它拥有参数。具体包含两个参数:
1: resolve() 执行器函数成功时的处理函数 2: reject() 执行器函数失败时的处理函数
通过以下代码示例,可以清晰了解创建Promise的语法结构:
let executor = function (resolve, reject) {};
let promise = new Promise(executor);
基于上述代码示例,接下来通过Node.js中读取文件的实例进行演示:
let executor = function (resolve, reject) {
let fs = require('fs');
fs.readFile('data.txt', {encoding: 'utf8'}, function (error, content) {
if (error) {
reject(error); //在异步行为失败时,调用reject()方法
return;
}
resolve(content); //在异步行为成功时,调用resolve()方法
});
};
let promise = new Promise(executor);
对上述代码的解释如下:
1: 创建Promise,包裹异步程序
Promise本身不执行实际的异步程序。我们将异步程序包裹在Promise中,目的是将异步处理的结果传递给Promise,以便后续利用其提供的接口函数(如then()或catch())处理结果。
2: 在Promise的executor函数中调用真正的异步操作函数。
我们在executor函数中调用fs.readFile()函数。该函数属于异步行为,其第三个参数为回调函数,用于接收文件读取结果(失败时的error和成功时的content)。
3: 将异步程序的结果传递给Promise
在fs.readFile()的回调函数中,文件读取成功时调用resolve()方法,失败时调用reject()方法。通过这两个函数的参数传入成功或失败的结果,为Promise在fulfilled或rejected状态时提供数据。
处理Promise结果
四:编写Promise结果处理程序
前文已介绍如何将异步处理事件包裹在Promise中,并通过resolve()和reject()传递结果。最后一步是使用结果数据(类比现实生活中的“验证承诺”)。Promise提供两个方法处理结果:Promise.prototype.then()和Promise.prototype.catch()。下面分别介绍它们的功能:
1:Promise.prototype.then()
then()方法接收两个函数类型的参数:
1: 第一个参数为Promise在fulfilled状态(成功状态)时的回调方法 2: 第二个参数为Promise在rejected状态(失败状态)时的回调方法 以之前的读取文件为例,查看then()方法的使用:
let executor = function (resolve, reject) {
let fs = require('fs');
fs.readFile('data.txt', {encoding: 'utf8'}, function (error, content) {
if (error) {
reject(error); //在异步行为成功时,调用reject()方法
return;
}
resolve(content); //在异步行为失败时,调用resolve()方法
});
};
let promise = new Promise(executor);
//处理成功和失败的情况
promise.then(function (content) {
console.log(content);
}, function (error) {
console.log(error)
});
这两个回调函数的参数即之前异步处理的结果数据。第一个函数的参数对应resolve()的参数content,第二个回调函数对应reject()的参数error。这样即可在两个回调函数中获取数据,并根据业务需求编写相应的结果处理程序。
需要注意的是,这两个回调函数参数并非必须,不强制要求同时处理。以下代码列出了两种结果处理程序,语法上均合法。但在正常需求下,通常需要对成功和失败都进行处理。
//只处理成功的情况
promise.then(function (content) {
console.log(content);
});
//只处理失败的情况
promise.then(null, function (error) {
console.log(error)
});
2: Promise.prototype.catch()
catch()方法仅接收一个参数:一个只处理rejected状态的回调函数。有人可能会疑问,既然then()已能同时处理两种状态,为何还需要catch()方法?
原因在于前文提到的,在then()方法中,并不强制要求提供处理rejected的回调函数。Promise有一个特性:如果未添加rejected处理函数,所有失败将被自动忽略。
部分开发者可能只关注成功状态而忽略提供rejected处理函数,从而给程序埋下隐患,导致不良的用户体验。catch()方法提供了一种明确处理rejected的方式,避免了在then()中因非必须参数而易被忽略的问题。
背景说明至此,我们来看看catch()如何使用:
promise.catch(function (error) {
console.log(error)
})
其实用法很简单,它等价于带有reject处理函数的then():
promise.then(null, function (error) {
console.log(error)
});
语法上并不要求完整的Promise处理程序必须包含catch()方法。如果您没有使用catch()的习惯,最好始终记得在使用then()时添加reject处理函数。
或者,如果您偶尔会忘记在then()里添加reject处理函数,那么记得使用catch()来提供安全保障。
以上即为关于Promise的基本概念和使用方法。在日常开发中,Promise的使用非常频繁且实用,因此掌握Promise是一项必备技能。希望对大家的学习有所帮助,也希望大家多多支持本站。
JS语法错误会阻止加载吗?区分SyntaxError与资源加载失败
2026-11-05 16:08:46
JavaScript常见SyntaxError语法错误排查与修复方法
2026-11-05 13:58:44
JS中slice、substring和substr截取字符串的区别
2026-11-05 13:43:47
JS 转 TS 手动迁移最佳实践:从配置 tsconfig 到消除 any 类型
2026-11-05 11:53:32
为什么JS数组push后得到的是数字而不是数组?
2026-11-05 09:59:18
