Promise是异步编程的核心概念之一。代表一个可能尚未完成的操作,并提供了一种机制来处理该操作最终的成功或失败。具体来说,Promise是由异步函数返回的对象,能够指示该操作当前所处的状态。 当Promise被创建时,它会处于“待定”(Pending)状态,这意味着操作尚未完成。在这个阶段,Promise对象可以通过其提供的方法来注册回调函数,以便在操作最终完成后进行相应的处理。一旦操作完成,Promise的状态会变为“已兑现”(Fulfilled),表示成功;或者变为“已拒绝”(Rejected),表示失败。 除了基本的状态管理,Promise还提供了链式调用的能力,使得开发者可以以更加清晰和可读的方式进行异步操作的组合。例如,可以使用.then()方法处理成功的结果,使用.catch()方法处理错误,甚至可以通过.finally()方法执行一些清理工作,无论操作是成功还是失败。

Promise 是一个代表异步操作最终完成(或失败)及其结果值的对象。它有三种状态:
一旦 Promise 被 fulfilled 或 rejected,它的状态就会被锁定,后续的状态无法再改变。
Promise是通过 new Promise() 构造函数创建的。这个构造函数接受一个执行器(executor)函数作为参数,该函数接收两个参数:resolve 和 reject。通过调用 resolve 来标记Promise对象状态为已兑现(fulfilled),而通过调用 reject 则将其标记为已拒绝(rejected)。
const myPromise = new Promise((resolve, reject) => {
// 模拟异步操作
const success = true; // 假设操作成功
if (success) {
resolve('操作成功'); // 标记Promise为已兑现
} else {
reject('操作失败'); // 标记Promise为已拒绝
}
});一旦创建了Promise对象,可以利用 then() 方法处理Promise对象状态为已兑现时的返回值,也可以使用 catch() 方法来处理Promise对象状态为已拒绝时的错误信息。
myPromise
.then(result => {
console.log(result); // 打印: 操作成功
})
.catch(error => {
console.error(error); // 打印错误信息
});当Promise对象状态为已兑现时,then()方法会调用传入的回调函数并输出成功的信息;当Promise对象状态为已拒绝时,则会调用catch()方法中的回调函数输出错误信息。
fetch() APIfetch() API 是一个现代的网络请求接口,广泛用于发起网络请求并处理响应。它返回一个 Promise,使得异步操作的管理变得更加简单和直观。fetch() 通常用于获取网络资源,如 RESTful API 的数据。
fetch() 使用以下是使用 fetch() 发送 GET 请求并处理响应的基本示例:
fetch('https://api.example.com/data')
.then(response => {
// 检查响应是否成功
if (!response.ok) {
throw new Error('网络响应失败');
}
return response.json(); // 解析 JSON 数据
})
.then(data => {
console.log(data); // 输出返回的数据
})
.catch(error => {
console.error('请求失败:', error); // 捕获并输出错误信息
});fetch() 函数向指定的 URL 发送了 GET 请求。.then() 方法处理。如果响应不正常(例如状态码不是 200-299),则会抛出一个错误。response.json() 方法解析 JSON 格式的数据,并在随后的 .then() 中使用解析后的数据。除了发送 GET 请求外,fetch() 还可以用来发送 POST 请求。在发送 POST 请求时,可以传递一个包含请求体的配置对象。
fetch('https://api.example.com/data', {
method: 'POST', // 指定请求方法为 POST
headers: {
'Content-Type': 'application/json' // 设置请求头部信息
},
body: JSON.stringify({ key: 'value' }) // 转换请求体为 JSON 字符串
})
.then(response => {
// 检查响应状态
if (!response.ok) {
throw new Error('网络响应失败');
}
return response.json(); // 解析 JSON 数据
})
.then(data => {
console.log(data); // 输出返回的数据
})
.catch(error => {
console.error('请求失败:', error); // 捕获并输出错误信息
});method: 'POST' 指明请求类型。Content-Type 为 application/json,表明请求体的格式。body 属性将请求体转换为 JSON 字符串,以便于服务器理解。Promise 提供了链式调用的能力,这意味着可以在一个 then() 处理程序中返回另一个 Promise,从而形成异步操作的链式结构。
下面示例中,展示了如何使用 Promise 的链式调用来依次请求两个不同的数据资源:
fetch('https://api.example.com/data1')
.then(response => response.json())
.then(data1 => {
console.log('数据1:', data1);
return fetch('https://api.example.com/data2'); // 返回另一个 Promise
})
.then(response => response.json())
.then(data2 => {
console.log('数据2:', data2);
})
.catch(error => {
console.error('请求失败:', error);
});fetch() 请求获取第一个数据资源,通过 .then() 解析响应为 JSON 数据。.then() 处理程序中,我们输出第一个数据并返回另一个 fetch() 请求,以发起第二个异步操作。fetch() 请求获取第二个数据资源,通过 .then() 解析响应为 JSON 数据。.then() 处理程序输出第二个数据。当一个 Promise 被 resolve 时,它会传递给下一个 .then() 处理程序。如果在 .then() 处理程序中返回一个新的 Promise,则当前 Promise 的状态将取决于此新 Promise 的状态。这样就形成了一条链,依次处理多个异步操作。
在使用 Promise 进行异步操作时,错误处理是非常重要的一部分。通过在 Promise 链中使用 catch() 方法,可以捕获整个链中发生的错误,并进行相应的处理。
示例中展示了如何在一个 Promise 链中处理错误:
fetch('https://api.example.com/data1')
.then(response => {
if (!response.ok) {
throw new Error('网络响应失败');
}
return response.json();
})
.then(data1 => {
console.log('数据1:', data1);
return fetch('https://api.example.com/data2');
})
.then(response => {
if (!response.ok) {
throw new Error('网络响应失败');
}
return response.json();
})
.then(data2 => {
console.log('数据2:', data2);
})
.catch(error => {
console.error('请求失败:', error);
});.then() 处理程序都会检查响应是否成功。如果不成功,则抛出一个 Error。catch() 方法用于捕获所有发生的错误,包括前面任何一个 Promise 的错误。.then() 处理程序会被跳过,直接执行 catch() 中的错误处理逻辑。Promise 链中的任何一个 Promise 的错误都会传递到最近的 catch() 方法中。这样做可以确保整个链中的任何一个步骤出现问题时都能得到正确的处理。catch() 方法也可以用来统一处理整个链中的错误,使代码更加清晰和易于维护。
讨论 Promise 中了解一些重要的术语很有帮助。以下是一些常见的 Promise 术语及其含义:
new Promise() 创建的对象,代表一个异步操作的最终完成或失败。finally()下面的示例展示了如何使用 finally() 方法来进行清理工作,无论 Promise 是成功还是失败,finally() 中的回调都会被执行:
fetch('https://api.example.com/data')
.then(response => {
if (!response.ok) {
throw new Error('网络响应失败');
}
return response.json();
})
.then(data => {
console.log(data);
})
.catch(error => {
console.error('请求失败:', error);
})
.finally(() => {
console.log('请求完成,无论成功或失败。');
});finally() 中的回调都会被执行,用来进行一些清理工作或其他必要的操作。处理多个异步操作时,可以使用 Promise.all() 和 Promise.race() 这两种方法来组合多个 Promise 对象。
Promise.all() 方法接收一个包含多个 Promise 的数组作为参数,只有当所有 Promise 都成功时,返回的 Promise 才会成功。如果其中任何一个 Promise 失败,则返回的 Promise 也会失败。
const promise1 = fetch('https://api.example.com/data1');
const promise2 = fetch('https://api.example.com/data2');
Promise.all([promise1, promise2])
.then(responses => {
return Promise.all(responses.map(response => {
if (!response.ok) {
throw new Error('网络响应失败');
}
return response.json();
}));
})
.then(data => {
console.log('数据:', data);
})
.catch(error => {
console.error('请求失败:', error);
});Promise.race() 方法返回一个 Promise,该 Promise 只会在第一个 Promise 解决或拒绝时解决。即使其他 Promise 还没有完成,只要有一个 Promise 在之前完成或失败,race() 返回的 Promise 就会立即解决。
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, '第一个 Promise 完成');
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(reject, 50, '第二个 Promise 失败');
});
Promise.race([promise1, promise2])
.then(result => {
console.log(result); // 不会执行,因为 promise2 先失败
})
.catch(error => {
console.error(error); // 输出: 第二个 Promise 失败
});async 和 await 是 ES2017 引入,用于更简洁地处理 Promise。async 关键字用于定义异步函数,await 用于等待 Promise 解决。
async function fetchData() {
try {
const response1 = await fetch('https://api.example.com/data1');
if (!response1.ok) {
throw new Error('网络响应失败');
}
const data1 = await response1.json();
console.log('数据1:', data1);
const response2 = await fetch('https://api.example.com/data2');
if (!response2.ok) {
throw new Error('网络响应失败');
}
const data2 = await response2.json();
console.log('数据2:', data2);
} catch (error) {
console.error('请求失败:', error);
}
}
fetchData();async 函数总是返回一个 Promise,即使函数内没有显式返回值。下面的示例展示了这一点:
async function example() {
return 'Hello, World!';
}
example().then(message => {
console.log(message); // 输出: Hello, World!
});我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=tfvwshelnu3w