Promise 的详细用法
Promise 是 JavaScript 中用于处理异步操作的对象,它代表一个异步操作的最终完成(或失败)及其结果值。
基本概念
Promise 有三种状态:
- pending:初始状态,既不是成功,也不是失败状态
- fulfilled:意味着操作成功完成
- rejected:意味着操作失败
创建 Promise
const myPromise = new Promise((resolve, reject) => {
// 异步操作
if (/* 操作成功 */) {
resolve('成功的结果');
} else {
reject('失败的原因');
}
});
使用 Promise
then() 方法
myPromise.then(
(value) => {
// 成功时的处理
console.log(value); // '成功的结果'
},
(error) => {
// 失败时的处理(可选)
console.error(error); // '失败的原因'
}
);
catch() 方法
myPromise
.then((value) => {
console.log(value);
})
.catch((error) => {
console.error(error);
});
finally() 方法
myPromise
.then((value) => {
console.log(value);
})
.catch((error) => {
console.error(error);
})
.finally(() => {
console.log('无论成功或失败都会执行');
});
Promise 链式调用
doSomething()
.then((result) => doSomethingElse(result))
.then((newResult) => doThirdThing(newResult))
.then((finalResult) => {
console.log(`最终结果: ${finalResult}`);
})
.catch(failureCallback);
Promise 静态方法
Promise.resolve()
const resolvedPromise = Promise.resolve('立即解析的值');
resolvedPromise.then((value) => console.log(value)); // '立即解析的值'
Promise.reject()
const rejectedPromise = Promise.reject('立即拒绝的原因');
rejectedPromise.catch((reason) => console.error(reason)); // '立即拒绝的原因'
Promise.all()
等待所有 promise 完成,或第一个 promise 被拒绝
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve) => {
setTimeout(resolve, 100, 'foo');
});
Promise.all([promise1, promise2, promise3]).then((values) => {
console.log(values); // [3, 42, "foo"]
});
Promise.allSettled()
等待所有 promise 完成(无论成功或失败)
const promise1 = Promise.resolve(3);
const promise2 = new Promise((_, reject) => {
setTimeout(reject, 100, 'error');
});
Promise.allSettled([promise1, promise2]).then((results) => {
console.log(results);
// [
// { status: 'fulfilled', value: 3 },
// { status: 'rejected', reason: 'error' }
// ]
});
Promise.race()
返回第一个 settled 的 promise(无论成功或失败)
const promise1 = new Promise((resolve) => {
setTimeout(resolve, 500, 'one');
});
const promise2 = new Promise((resolve) => {
setTimeout(resolve, 100, 'two');
});
Promise.race([promise1, promise2]).then((value) => {
console.log(value); // "two"
});
Promise.any()
返回第一个 fulfilled 的 promise(忽略 rejections)
const promise1 = Promise.reject(0);
const promise2 = new Promise((resolve) => {
setTimeout(resolve, 100, 'quick');
});
const promise3 = new Promise((resolve) => {
setTimeout(resolve, 500, 'slow');
});
Promise.any([promise1, promise2, promise3]).then((value) => {
console.log(value); // "quick"
});
错误处理最佳实践
- 总是使用 catch() 处理错误
- 在链式调用中,一个 catch() 可以处理前面所有 then() 中的错误
- 避免在 then() 中同时使用第二个参数和 catch()
// 不好的做法
promise.then(
successCallback,
errorCallback
);
// 好的做法
promise
.then(successCallback)
.catch(errorCallback);
实际应用示例
异步请求封装
function fetchData(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onload = () => resolve(xhr.responseText);
xhr.onerror = () => reject(xhr.statusText);
xhr.send();
});
}
fetchData('https://api.example.com/data')
.then((data) => {
console.log('成功获取数据:', data);
return JSON.parse(data);
})
.then((json) => {
console.log('解析后的JSON:', json);
})
.catch((error) => {
console.error('请求失败:', error);
});
多个异步操作顺序执行
function asyncOperation1() {
return new Promise((resolve) => {
setTimeout(() => resolve('操作1完成'), 1000);
});
}
function asyncOperation2(input) {
return new Promise((resolve) => {
setTimeout(() => resolve(`${input} -> 操作2完成`), 1500);
});
}
asyncOperation1()
.then((result1) => {
console.log(result1);
return asyncOperation2(result1);
})
.then((result2) => {
console.log(result2);
});
Promise 是现代 JavaScript 异步编程的基础,也是 async/await 语法的基础。掌握 Promise 的使用对于编写清晰、可维护的异步代码至关重要。