/**
*
* Promise是ES6引入的异步编程解决方案,用于处理异步操作。它代表一个未来才会知道结果的值,可以将异步操作以同步的流程表达出来,
避免回调地狱。
Promise 三种状态
Pending(进行中):初始状态
Fulfilled(已成功):操作成功完成
Rejected(已失败):操作失败
状态特点:
状态只能从 Pending → Fulfilled 或 Pending → Rejected
状态一旦改变就不会再变,任何时候都可以得到这个结果
一、Promise 实例方法
1. then(onFulfilled成功回调函数, onRejected失败回调函数)
2. catch(onRejected失败回调函数):捕获错误
3. finally(onFinally回调函数):无论成功失败都会执行,常用于关闭加载动画、释放资源等
*
二、Promise 静态方法
1. Promise.resolve():返回一个已成功的 Promise 对象
Promise.resolve('success').then(result => console.log(result)); // 将值转换为 fulfilled 状态的 Promise
等价于
new Promise(resolve => resolve('success'));
2. Promise.reject():返回一个已失败的 Promise 对象
Promise.reject(new Error('失败')).catch(error => console.error(error)); // 返回rejected 状态的 Promise
3. Promise.all([p1, p2, p3]):并行执行多个 Promise,全部成功才成功,只要有一个失败,就会进入 catch。并行请求多个接口
4. Promise.allSettled([p1, p2]):等待所有 Promise 完成(无论成功失败)
5. Promise.race([p1, p2]): 返回最快完成的 Promise(无论成功失败)
6. Promise.any([p1, p2]):返回第一个成功的 Promise,全部失败才失败
* 什么时候使用Promise
* 1.先异步,后处理
*
* 为什么用Promise
* 解决回调地狱问题,实现每一步操作的分离
*
*
* 有先一步操作(它是一个异步操作,需要过一段时间才能完成),之后再进行下一步操作
*/
function getInfo(name) {
let xhr = new XMLHttpRequest()
//异步操作,回调函数
xhr.onloadend = function() {
let data = JSON.parse(xhr.responseText)
console.log(data)
return data
}
xhr.open('GET',`http://xxx?sname=${name}`)
xhr.send()
}
let res = getInfo('zhangsan')
console.log(res)//这里res是undefined
//用Promise解决
function getInfo(name) {
return new Promise((resolve,reject)=> {
let xhr = new XMLHttpRequest()
xhr.onloadend = function() {
let data = JSON.parse(xhr.responseText)
if(data) {
resolve(data)
}else {
reject('没有得到数据')
}
}
xhr.open('GET',`http://xxx?sname=${name}`)
xhr.send()
})
}
let resPromise = getInfo('zhangsan')
resPromise.then(showTable)
function showTable(data) {
let str=`<table>
<tr>
<th>编号</th>
<th>姓名</th>
</tr>`
str+=data.map(item=>`<tr>
<td>${item.sid}</td>
<td>${item.sname}</td>
</tr>`).join('')
str+='</table>'
}
//_----需求:第一步:根据学生名称查找他的信息。第二步:再根据学生信息中编号查询他的成绩。第三步:根据成绩信息中的id查询判卷老师
function getData(sname) {
return new Promise((resolve,reject)=>{
let xhr = new XMLHttpRequest()
xhr.onloadend = function() {
let data = JSON.parse(xhr.responseText)
if(data) {
resolve(data[0].sid)
}else {
reject('没有查询到个人信息')
}
}
xhr.open('GET',`http://xxx?sname=${sname}`)
xhr.send()
})
}
function getScore(sid) {
return new Promise((resolve,reject)=>{
let xhr = new XMLHttpRequest()
xhr.onloadend = function() {
let score = JSON.parse(xhr.responseText)
if(score) {
resolve(score.tid)
}else {
reject('没有查询到成绩')
}
}
xhr.open('GET',`http://xxx?sid=${sid}`)
xhr.send()
})
}
function getTeacher(tid) {
return new Promise((resolve,reject)=>{
let xhr = new XMLHttpRequest()
xhr.onloadend = function() {
let teacher = JSON.parse(xhr.responseText)
if(teacher) {
console.log('查询到老师',teacher)
}else {
reject('没有找到老师信息')
}
}
xhr.open('GET',`http://xxx?tid=${tid}`)
xhr.send()
})
}
//----用Promise
getData('张宁')
.then(getScore)
.then(getTeacher)
.catch((reason)=>{
console.log('捕获到报错',reason)
})
//----用async/await 用同步代码的方式写异步代码
async function getResult(sname) {
let sid = await getData(sname)
let tid = await getScore(sid)
let teacher = await getTeacher(tid)
}
getResult('郭晓晓').catch((reason)=>{
console.log('捕获到报错',reason)
})
//-------------------Promise静态方法详解
1.Promise.all
参数: 接收一个可迭代对象(如数组),通常包含多个Promise。
行为: 它返回一个新的Promise。当所有输入的Promise都成功完成(fulfilled)时,它才成功,结果是一个数组,按输入顺序收集所有成功值。如果其中任何一个Promise失败(rejected),它会立即失败,并返回这个失败的原因
使用场景: 适用于多个强依赖的异步任务必须全部成功的场景。
示例: 一个页面需要同时加载用户基本信息、好友列表和消息通知,这三部分数据都获取成功后才能渲染页面
async function getAll() {
const [userInfo,friends,messages] = await Promise.all([fetch('/api/user'),fetch('/api/friends'),fetch('/api/messages')])
}
2.Promise.allSettled
参数: 一个可迭代对象。
行为: 它会等待所有输入的Promise都“敲定”(settled,即要么成功要么失败)。它自己永远不会失败,总是成功返回一个对象数组。每个对象都有一个status字段('fulfilled'或 'rejected'),成功对象有value属性,失败对象有reason属性
使用场景: 适用于需要了解每个异步任务最终结果的情况,特别是当部分失败不影响整体流程时。
示例: 批量上传多个文件,需要知道每个文件是上传成功还是失败,以便对失败的文件进行重试或提示
const results = await Promise.allSettled([
uploadFile(file1),
uploadFile(file2),
uploadFile(file3)
]);
const successfulUploads = results.filter(r => r.status === 'fulfilled');
const failedUploads = results.filter(r => r.status === 'rejected');
3.Promise.any
参数: 一个可迭代对象。
行为: 当输入的Promise中有任何一个成功(fulfilled),它就会立即成功,并返回那个成功的值。只有当所有的Promise都失败时,它才会失败,并返回一个AggregateError,其中包含所有失败的原因
使用场景: 适用于从多个来源获取相同资源,只要有一个成功即可的场景,常用于提高可用性和冗余备份。
示例: 从多个镜像服务器请求同一个资源,使用最先响应的那个。
const fastestResponse = await Promise.any([
fetch('https://mirror1.com/data'),
fetch('https://mirror2.com/data'),
fetch('https://mirror3.com/data')
]);
4. Promise.race
参数: 一个可迭代对象。
行为: 它采纳第一个“敲定”(settled)的Promise的结果,无论这个结果是成功还是失败。后续Promise的结果会被忽略。
使用场景:
设置超时控制: 为一个异步操作设置时间限制。
// 如果 fetchData 在5秒内没有响应,则触发超时
const dataOrTimeout = await Promise.race([
fetchData(),
new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), 5000))
]);
console