Promise 是一个用于进行异步编程的 JavaScript 对象,它支持使用 .then() 和 .catch() 方法来处理异步操作的结果和错误。然而,很多开发者不清楚 .then() 和 .catch() 方法可以返回 Promise,而这个特性在某些场景下非常有用。本文将深入探讨 Promise.then 和 Promise.catch 中返回 Promise 的使用方法,帮助读者更好地理解和使用 Promise。
Promise.then 中返回 Promise
在 Promise.then 中返回 Promise 可以实现链式调用,便于处理多个异步操作。以下是一个示例:
getUserInfo()
.then((userInfo) => {
return getUserPosts(userInfo.id);
})
.then((posts) => {
// 处理用户所有的 post
});在上面的代码中,getUserInfo() 函数返回一个 Promise,用于获取用户信息。在第一个 .then() 中,我们通过 .then() 的返回值,返回了一个新的 Promise,用于获取用户的 post。通过这种链式调用方式,我们可以在不嵌套回调函数的情况下,方便地处理多个异步操作。
Promise.catch 中返回 Promise
当 Promise 被 reject 时,.catch() 方法可以捕获错误,并进行处理。在 Promise.catch 中返回 Promise,可以实现 Promise 捕获错误并重试的功能。以下是一个示例:
// www.javascriptcn.com code example
function fetchData() {
return fetch('https://example.com/data.json')
.then((response) => {
if (!response.ok) {
throw new Error('Response not ok');
}
return response.json();
});
}
function fetchWithRetry() {
return fetchData().catch((error) => {
// 如果出错了,等待一段时间后重试
return new Promise((resolve) => setTimeout(resolve, 1000))
.then(fetchWithRetry);
});
}在上面的代码中,fetchData() 函数返回一个 Promise,用于获取数据。如果数据请求失败,会通过 throw new Error() 抛出一个错误。在 fetchWithRetry() 函数中,我们尝试用 .catch() 捕获 fetchData() 的错误。如果 fetchData() 失败,我们会等待一段时间再尝试重新执行 fetchData()。这个过程在 .catch() 方法返回一个新的 Promise 后,通过 .then() 进行处理。
代码示例
为了方便读者更好地理解,这里提供一个完整的示例代码,展示了 Promise.then 和 Promise.catch 中返回 Promise 的使用方法:
// www.javascriptcn.com code example
function getPostById(postId) {
return new Promise((resolve, reject) => {
if (typeof postId !== 'number') {
reject(new Error('postId should be a number'));
}
setTimeout(() => {
resolve({ id: postId, content: 'Post Content' });
}, 1000);
});
}
function getUserInfoByPostId(postId) {
return getPostById(postId)
.then((post) => {
return new Promise((resolve, reject) => {
if (post.id % 2 === 0) {
reject(new Error('Please use odd postId'));
}
setTimeout(() => {
resolve({ userId: post.id + 1, userName: 'User Name' });
}, 1000);
});
});
}
function loginByUserId(userId) {
return new Promise((resolve, reject) => {
if (userId % 2 === 0) {
reject(new Error('Only odd userId can login'));
}
setTimeout(() => {
resolve('Token');
}, 1000);
});
}
getUserInfoByPostId(1)
.then((userInfo) => {
console.log(`getUserInfoByPostId return: ${JSON.stringify(userInfo)}`);
return loginByUserId(userInfo.userId);
})
.then((token) => {
console.log(`loginByUserId return: ${token}`);
})
.catch((error) => {
console.error(`Error: ${error.message}`);
return 'error';
});
getUserInfoByPostId(2)
.then((userInfo) => {
console.log(`getUserInfoByPostId return: ${JSON.stringify(userInfo)}`);
return loginByUserId(userInfo.userId);
})
.then((token) => {
console.log(`loginByUserId return: ${token}`);
})
.catch((error) => {
console.error(`Error: ${error.message}`);
return 'error';
});在上面的代码中,我们构建了 3 个用于模拟异步请求的函数:getPostById()、getUserInfoByPostId() 和 loginByUserId()。利用这些函数,我们构建了一个简单的异步执行流程:
- 通过调用 getUserInfoByPostId() 函数,获取 postId 为 1 的 post 的用户信息。
- 如果 postId 是偶数,则 getUserInfoByPostId() 函数会返回错误。
- 通过调用 loginByUserId() 函数,并使用 getUserInfoByPostId() 返回的用户 ID 登录,获取 Token。
- 如果 userId 是偶数,则 loginByUserId() 函数会返回错误。
第一个 Promise 执行后,返回的 Promise 中的 .then() 和 .catch() 同样可以返回 Promise,成为它们自己 Promise 链的一部分。根据上面的代码,我们可以轻松地新增和删除 Promise,实现代码逻辑的调整。
结语
本文介绍了 Promise.then 和 Promise.catch 中返回 Promise 的使用方法,并提供了一个详细的示例代码,帮助读者更好地理解和使用 Promise。通过这种方式,我们可以充分发挥 Promise 的链式调用特性,实现更加复杂的异步操作。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d82422a941bf7134e89ced