JavaScript Promise 状态、用法及核心方法详解
本文深入解析 JavaScript 中 Promise 的核心机制,涵盖 Pending、Fulfilled 和 Rejected 三种状态。详细讲解 new Promise 的创建方式、then 与 catch 的链式调用,以及 finally、all、race 和 allSettled 等高级方法。附带简化版源码实现,帮助开发者理解异步流程控制与错误处理。
1. Promise 简介
在 JavaScript 中,Promise 是一种专门用于处理异步操作的机制。
作为 ES6(ECMAScript 2015)引入的语言特性,Promise 旨在解决回调地狱(callback hell)问题,同时提升异步代码的可读性与可维护性。
可以将 Promise 视为对异步操作的封装,它代表了一个从进行中到已完成的操作过程,并能返回操作的结果或错误信息。
一个 Promise 对象拥有三种状态:
- Pending(进行中):初始状态,表示操作正在进行中,尚未完成。
- Fulfilled(已完成):表示操作已成功完成。
- Rejected(已失败):表示操作失败或出现错误。
创建 Promise 对象可以使用 new Promise() 构造函数,该函数接受一个执行器函数(executor function)作为参数。
执行器函数在 Promise 实例化时立即执行,它接收两个参数,通常命名为 resolve 和 reject。
在执行器函数内部执行异步操作,并根据操作结果调用 resolve 或 reject。
以下是创建 Promise 对象的示例:
const promise = new Promise((resolve, reject) => {
// 异步操作,可以是AJAX请求、定时器等
setTimeout(() => {
const randomNumber = Math.random();
if (randomNumber < 0.5) {
// 操作成功,调用resolve并传递结果
resolve(randomNumber);
} else {
// 操作失败,调用reject并传递错误信息
reject(new Error('操作失败'));
}
}, 1000);
});
Promise 对象提供了两个主要方法来处理操作完成后的结果:then() 和 catch()。
then() 方法接收两个回调函数作为参数,第一个用于处理操作成功的结果,第二个用于处理操作失败的情况。
这两个回调函数可以返回新的 Promise 对象,从而支持链式调用。
以下是使用 then() 方法处理 Promise 对象的示例:
promise.then((result) => {
console.log('操作成功,结果为:', result);
}).catch((error) => {
console.error('操作失败,错误信息为:', error);
});
在上述示例中,如果操作成功,将调用第一个回调函数并打印结果;如果操作失败,则调用 catch() 方法中的回调函数并打印错误信息。
除了 then() 和 catch(),Promise 还提供了其他一些方法,如 finally()、all() 和 race() 等,用于更高级的操作和处理多个 Promise 对象。
希望这个简单的讲解可以帮助你理解 JavaScript 中的 Promise。
Promise 是一种非常强大和灵活的异步编程工具,它可以显著提高代码的可读性和可维护性。
2. Promise 还提供了其他一些方法
主要包括哪些:
除了 then() 和 catch() 方法,Promise 还提供了以下常用的方法:
finally(onFinally):
该方法在 Promise 对象无论是被解析(fulfilled)还是被拒绝(rejected)时都会执行,无论前面的操作结果如何。
它接收一个回调函数作为参数,在 Promise 执行结束后调用该回调函数。
promise.finally(() => {
console.log('Promise执行结束');
});
all(iterable):
该方法接收一个可迭代对象(比如数组)作为参数,返回一个新的 Promise 对象。
这个新的 Promise 对象在可迭代对象中的所有 Promise 对象都解析(fulfilled)后才会解析,或者只要有一个 Promise 对象被拒绝(rejected)就会被拒绝。
返回的 Promise 对象的解析值是一个数组,包含了可迭代对象中所有 Promise 对象的解析值,顺序与可迭代对象中的顺序一致。
const promises = [promise1, promise2, promise3];
Promise.all(promises)
.then((results) => {
console.log('所有Promise对象都已解析', results);
})
.catch((error) => {
console.error('至少有一个Promise对象被拒绝', error);
});
ace(iterable):
该方法接收一个可迭代对象(比如数组)作为参数,返回一个新的 Promise 对象。
这个新的 Promise 对象将解析(fulfilled)或拒绝(rejected)取决于可迭代对象中最先解析或拒绝的 Promise 对象。
返回的 Promise 对象将具有第一个解析或拒绝的 Promise 对象的解析值或拒绝原因。
const promises = [promise1, promise2, promise3];
Promise.race(promises)
.then((result) => {
console.log('第一个解析或拒绝的Promise对象', result);
})
.catch((error) => {
console.error('第一个拒绝的Promise对象', error);
});
allSettled(iterable):
该方法接收一个可迭代对象(比如数组)作为参数,返回一个新的 Promise 对象。
这个新的 Promise 对象在可迭代对象中的所有 Promise 对象都解析或拒绝后才会解析,不管结果如何,返回的 Promise 对象的解析值是一个包含所有 Promise 对象的解析状态和值的数组。
const promises = [promise1, promise2, promise3];
Promise.allSettled(promises)
.then((results) => {
console.log('所有Promise对象都已解析或拒绝', results);
});
这些是 Promise 提供的一些常用方法,可以根据具体需求选择使用。
它们使得处理异步操作更加便捷和灵活,提供了更多的控制和处理方式。
3. Promise 常用方法的简化版本的源码实现
finally(onFinally):
Promise.prototype.finally = function(onFinally) {
return this.then(
(value) => Promise.resolve(onFinally()).then(() => value),
(reason) =>
Promise.resolve(onFinally()).then(() => {
throw reason;
})
);
};
all(iterable)
javascript
Copy code
Promise.all = function(iterable) {
const promises = Array.from(iterable);
return new Promise((resolve, reject) => {
if (promises.length === 0) {
resolve([]);
} else {
const results = [];
let completedCount = 0;
promises.forEach((promise, index) => {
Promise.resolve(promise)
.then((value) => {
results[index] = value;
completedCount++;
if (completedCount === promises.length) {
resolve(results);
}
})
.catch(reject);
});
}
});
};
race(iterable):
Promise.race = function(iterable) {
return new Promise((resolve, reject) => {
const promises = Array.from(iterable);
promises.forEach((promise) => {
Promise.resolve(promise)
.then(resolve)
.catch(reject);
});
});
};
allSettled(iterable):
Promise.allSettled = function(iterable) {
const promises = Array.from(iterable);
return new Promise((resolve) => {
if (promises.length === 0) {
resolve([]);
} else {
const results = [];
let completedCount = 0;
promises.forEach((promise, index) => {
Promise.resolve(promise)
.then((value) => {
results[index] = { status: 'fulfilled', value };
completedCount++;
if (completedCount === promises.length) {
resolve(results);
}
})
.catch((reason) => {
results[index] = { status: 'rejected', reason };
completedCount++;
if (completedCount === promises.length) {
resolve(results);
}
});
});
}
});
};
请注意,这些源码实现是简化版本,用于说明 Promise 方法的基本概念和工作原理。
实际的 Promise 实现可能会更加复杂,涉及更多细节和错误处理机制。
这些实现仅提供了一个基本的参考,而非用于生产环境。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持本站。
JS处理含Emoji或中文的字符串转数组乱码问题
2026-11-05 16:12:28
JS怎么使用展开运算符合并对象
2026-11-05 14:42:18
ES6+环境下判断JS对象为空的简洁写法
2026-11-05 12:12:23
怎么通过replacer函数自定义JS中JSON的格式化输出
2026-11-05 11:19:44
JS正则表达式基础:字面量与RegExp构造函数的区别及常用元字符
2026-11-05 11:16:58
