文章目录
是什么
promise 是js中进行异步编程新的解决方案
用处
1、主要用于异步计算
2、可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果
3、可以在对象之间传递和操作promise,帮助我们处理队列
简单理解
let pro = new Promise((succ, err)=>{
// succ('成功信息'); //成功回调 执行then
err('错误信息') //失败回调 执行catch
})
pro.then(res=>{
console.log(res)
}).catch(err=>{
console.error(err)
})
连续then 链式写法
指定回调函数更加灵活
// 启动异步任务 => 返回promise对象 => 给promise对象绑定回调函数(甚至可以在异步完成之后)
let pro = new Promise((resole, reject)=>{
setTimeout(()=>{
if(Math.random()-0.5){
console.log("Promise resole")
resole("成功")
}else{
console.log("Promise reject")
reject("失败")
}
},1000)
})
setTimeout(()=>{
pro.then(res=>{
console.log("res:",res)
},err=>{
console.log("err:",err)
})
},5000)
链式写法 return 等同于返回成功状态
new Promise((succ, err)=>{
succ('成功信息'); //成功回调 执行then
}).then(res=>{
console.log('res1:',res)
return 'res1'
}).then(res=>{
console.log('res2:',res)
}).then(res=>{
console.log('res3:',res)
}).catch(err=>{
console.error(err)
})
链式写法案例
const repos = [
{type:'aa', id:1},
{type:'bb', id:2},
{type:'cc', id:6},
{type:'dd', id:5},
{type:'ff', id:7},
{type:'gg', id:4}
]
const reposText = [
{name:'reposTextaa', id:1, type:'aa'},
{name:'reposTextbb', id:2, type:'bb'},
{name:'reposTextcc', id:6, type:'cc'},
{name:'reposTextdd', id:5, type:'dd'},
{name:'reposTextff', id:4, type:'ff'},
{name:'reposTextgg', id:7, type:'gg'}
]
function getById(id){
return new Promise((succ, err)=>{
const repo = repos.find(item=> item.id === id)
if(repo){
succ(repo.type)
}else{
err('repo is not found')
}
})
}
function getBytext(type){
return new Promise((succ, err)=>{
const text = reposText.find(item=> item.type === type)
if(text){
succ(text)
}else{
err('reposText is not found')
}
})
}
getById(5)
.then(res=>{
return getBytext(res)
})
.then(res=>{
console.log(res)
})
.catch(err=>{
console.log(err)
})
Promise.all
2个promise 都成功 执行 .then回调 参数数组包含promise成功的参数
有一个promise 调用了错误回调 Promise.all执行.catch回调参数包含错误信息
const user = new Promise((succ, err)=>{ //只能返回一条数据
const text = reposText.find(item=> item.type === 'aa')
setTimeout(()=>{
if(text){
succ(text)
}else{
err('reposText is not found')
}
},1500)
})
const move = new Promise((succ, err)=>{ //只能返回一条数据
const text = reposText.find(item=> item.type === 'ff')
setTimeout(()=>{
if(text){
succ(text)
}else{
err('reposText is not found')
}
},500)
})
Promise.all([user, move])
.then(res=>{ //2个promise 都成功
const [userRes, moveRes] = res
console.log(userRes, moveRes)
// res[0] user返回的值
// res[1] move返回的值
}).catch(err=>{ //2个promise 有一个失败
console.log(err)
})
Promise.race
谁先执行完就返回谁的返回值
Promise.race([user, move])
.then(res=>{ //先执行完的promise成功
console.log(res)
}).catch(err=>{ //先执行完的promise失败
console.log(err)
})
promis异常穿透
- 当使用promise的then链式调用时,可以在最后指定失败的回调
- 前面然后操作出了异常,都会传到最后失败的回调中处理 是一步一步的穿透下去的
- catch后面 也可用正常使用then链式调用
new Peomise((resolve, reject)=>{
reject(1)
}).then(value=>{
console.log("onresolve1",value)
return 2
},
// reson => {thorw reson} //等同于隐式 的执行这个代码 1
// reson => {Promise.reject(reson )}
).then(value=>{
console.log("onresolve2",value)
return 3
},
// reson => {thorw reson} //等同于隐式 的执行这个代码 2
).then(value=>{
console.log("onresolve3",value)
return 4
},
// reson => {thorw reson} //等同于隐式 的执行这个代码 3
).catch(reson = > {
console.log("onReject1",reson )
})
中断promis
- 当使用promise的then链式调用时,在中间中断,不会在调用后面的回调函数
- 方法:在回调函数中返回一个 pendding状态的promise对象
return new Promise(()=>{}) //后面就不会执行失败或成功的回调了
new Promise((resolve, reject)=>{
resolve(1)
}).then(value=>{
console.log("onresolve1",value)
return new Promise(()=>{}) //返回一个pedding的promise 中断promise链式调用
}).then(value=>{
console.log("onresolve2",value)
})
Promise.allSettled
接收一个promise的数组,返回一个promise对象 状态是成功的
不论传入的promise返回成功或者失败 返回一个成功的promise对象
参数是 传入的promise的返回结果的数组 顺序相同
const p1 = new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('成功数据一')
},1000)
})
const p2 = new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('成功数据二')
},1000)
})
const p3 = new Promise((resolve, reject)=>{
setTimeout(()=>{
reject('失败数据二')
},1000)
})
Promise.allSettled([p1, p2]).then(res=>{ // p1 p1 都执行完
console.log(res)
})
Promise.allSettled([p1, p3]).then(res=>{
console.log(res)
})