Promise:JavaScript 异步编程的基石
TypeScript 简易教程
一、TypeScript前导
二、TypeScript基础语法
三、TypeScript变量
四、TypeScript Number+String类型
五、TypeScript运算符
六、TypeScript语句
七、TypeScript函数
八、TypeScript 容器类型
九、TypeScript 接口、类、对象
十、TypeScript 命名空间、模块、声明文件
十一、Promise:JavaScript 异步编程的基石
十二、TypeScript:Async Functions
Promise是JavaScript中用于处理异步操作的一种编程模式,自ECMAScript 6(ES6)起成为语言标准的一部分。它提供了一种更为优雅和可控的方式来处理异步操作,相较于传统的回调函数,Promise能够更好地解决“回调地狱”问题,增强代码的可读性和可维护性。本文将详细介绍Promise的概念、基本用法、链式调用、静态方法以及在实际开发中的应用案例。
一、Promise的基本概念
Promise代表一个异步操作的最终完成(或失败)及其结果的容器。它有三种状态:
- Pending(等待中):初始状态,既不是fulfilled也不是rejected。
- Fulfilled(已成功):表示操作成功完成,此时Promise的值为resolve传递的值。
- Rejected(已失败):表示操作失败,此时Promise的值为reject传递的原因。
一旦Promise从Pending变为Fulfilled或Rejected,它的状态就不可更改了,这称为Promise的不可逆性。
二、Promise的创建与使用
Promise构造函数接受一个函数作为参数,该函数接收两个参数:resolve
和reject
,分别用于改变Promise的状态。
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
const success = true;
if (success) {
resolve("操作成功");
} else {
reject("操作失败");
}
}, 2000);
});
resolve和reject 作为参数传递给Promise构造函数中的执行器(executor)函数。
- resolve: 此函数用于将Promise的状态从
pending
(等待中)变为fulfilled
(已成功)。当异步操作成功完成,或者你希望以某种成功的结果来解决Promise时,你应该调用resolve
函数。resolve
可以接受一个参数,这个参数将作为Promise的返回值传递给之后通过.then
方法注册的回调函数。这个参数可以是任何类型的值,包括普通数据、对象,甚至是另一个Promise。 - reject: 此函数用于将Promise的状态从
pending
变为rejected
(已失败)。当你希望以一个错误原因来拒绝Promise,表示异步操作未能成功完成时,应调用reject
函数。同样地,reject
也接受一个参数,该参数作为错误原因传递给之后通过.catch
方法注册的错误处理回调函数。这个参数通常是一个错误对象,用于描述失败的具体原因。
三、Promise的消费
then方法
.then()
方法用于指定在Promise变为fulfilled
状态时的回调函数,可以链式调用来处理多个后续操作。
myPromise.then(
value => console.log(value), // 当Promise成功时的处理
reason => console.error(reason) // 当Promise失败时的处理
);
catch方法
.catch()
方法用于指定在Promise变为rejected
状态时的回调函数,可以捕获前面链式调用中所有未被捕获的错误。
myPromise.catch(error => console.error(error));
四、Promise的链式调用
通过.then()
和.catch()
可以实现Promise的链式调用,这样可以按顺序执行一系列异步操作,每个操作都依赖于前一个操作的成功或失败。
myPromise
.then(result => {
console.log(result);
return "下一个操作";
})
.then(nextResult => console.log(nextResult))
.catch(error => console.error(error));
五、Promise的静态方法
Promise提供了几个静态方法,用于处理多个Promise的情况:
- Promise.all():等待所有的Promise都变为fulfilled状态,然后返回一个新的Promise,其结果是一个包含所有fulfilled状态的Promise结果的数组。如果有任何一个Promise变为rejected状态,则立即返回并拒绝,不等待其余的Promise。
// 假设有三个异步操作,分别返回 Promise
function fetchUser(userId) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(`Fetching user ${userId}...`);
// 模拟异步操作成功
resolve({ id: userId, name: `User ${userId}` });
// 如果想要模拟失败,可以使用 reject(new Error('Fetch failed'))
}, 1000 * userId);
});
}
// 使用 Promise.all 同时发起三个异步请求
const userIds = [1, 2, 3];
const userPromises = userIds.map(userId => fetchUser(userId));
Promise.all(userPromises)
.then(users => {
console.log("所有用户数据已获取:", users);
})
.catch(error => {
console.error("其中一个请求失败:", error);
});
- Promise.race():只要任意一个Promise变为fulfilled或rejected状态,就立即返回并结束,不等待其他Promise。
function timeout(ms) {
return new Promise((resolve, reject) => {
setTimeout(reject, ms, 'Timeout!');
});
}
function requestWithTimeout(url, timeoutMs) {
const requestPromise = fetch(url);
const timeoutPromise = timeout(timeoutMs);
return Promise.race([requestPromise, timeoutPromise])
.then(response => {
if (response === 'Timeout!') {
throw new Error('请求超时');
}
return response.json(); // 假设 fetch 成功后我们想处理响应数据
})
.catch(error => {
console.error('请求出错:', error.message);
});
}
// 假设我们有一个API请求,希望在5秒内完成,否则视为超时
requestWithTimeout('https://api.example.com/data', 5000)
.then(data => console.log('获取到的数据:', data))
.catch(error => console.error('请求失败:', error));
- Promise.resolve():直接创建一个fulfilled状态的Promise。
- Promise.reject():直接创建一个rejected状态的Promise。
六、应用示例
网络请求
function fetchData(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onload = () => {
if (xhr.status === 200) {
resolve(xhr.responseText);
} else {
reject(xhr.statusText);
}
};
xhr.onerror = () => reject(xhr.statusText);
xhr.send();
});
}
fetchData("https://api.example.com/data")
.then(data => console.log(data))
.catch(error => console.error(error));
本文系作者 @何健源 原创发布在思维代码站点。未经许可,禁止转载。
暂无评论数据