文章目录
作用:可以链式调用,解决回调地狱问题
promise的基本使用
promise初体验
<button id ="btn">click</button>
<script>
const btn = document.querySelector("#btn")
btn.addEventListener("click",function(){
const p = new Promise((resolve,reject)=>{
setTimeout(()=>{
let n = parseInt(Math.random()*100)
if(n < 30){
resolve(n)
}
else{
reject(n)
}
})
})
p.then((value)=>{
alert("中奖了"+value)
},(reason)=>{
alert("再接在历"+reason)
})
})
</script>
resolve:解决,将promise对象得状态设置为成功
reject:拒绝,将promise对象得状态设置为失败
then方法:第一个参数为resolve,另一个为失败后的调用
注意,promise中可一些异步操作,可以将成功的结果放入reject中,失败的放入resolve
异步编程:
fs文件操作
数据库操作
ajax请求
定时器
promise状态改变 [PromiseState]
pending变为resolved
pending变为rejected
只有这两种,并且一个promise对象只能改变一次,无论变为成功还是失败,都只会有一个结果数据
成功的结果数据一般为value,失败的结果为reason
promise 对象的值 [PromiseResult]
保存着异步任务成功/失败的结果
resolve
reject
promise的基本流程
在实例化promise对象时先会让状态置为pending当在promise中执行异步操作后,成功则执行resolve,生成promise对象,置为resolve状态,,在then中执行onReslove的回调,失败则相反
promise的api
1.promise的构造函数promise(excutor){}
1.excutor函数,执行器(resolve,reject)=>{}
2.resolve函数,内部定义成功后我们调用的函数value->{}
3.reject函数,内部定义失败时我们调用函数reason->{}
说明:excutor会在promise内部立即同步调用,异步操作在执行器中执行
const p = new Promise((reslove,reject)=>{
console.log(1)
if(1)reslove()
else reject()
})
console.log(2)
2.promise.prototype.then方法:(onResloved,onRejected)=>{}
1.onResloved函数,成功的回调函数(value)=>{}
2.onRejected函数:失败的回调函数reason=>{}
说明:指定用于得到成功value的成功回调和用于得到失败的reason的失败回调返回的是一个新的promise对象
3.promise.prototype.catch方法(onRejected)=>{}
1.onRejected函数,失败的回调函数(reason)=>{}
4.promise.resolve方法(Value)=>{}
1.value:成功的数据或者promise对象
说明:返回一个成功/失败的promise对象
let p1 = Promise.resolve(512)
//如果传入参数为非promise的对象,则返回的结果为promise对象
//如果传入的参数为promise对象,则参数的结果决定了resolve的结果
console.log(p1)
let p2 = Promise.resolve(new Promise((resolve,reject)=>{
resolve('ok')
}))
console.log(p2)
let p2 = Promise.resolve(new Promise((resolve,reject)=>{
reject('error')
}))
p2.catch(reason=>{
console.log(reason)
})
5.promise.reject方法(reason)=>{}
1.reason:失败的原因
说明:返回一个失败的promise对象
6.promise.all方法:(promise)=>{}
1.promise:包含n个promise的数组
说明:返回一个新的promise,只有所有的promise都成功才成功
let p1 = new Promise((reslove,reject)=>{
reslove('OK')
})
let p2 = Promise.resolve('success')
let p3 = Promise.resolve('yeah')
const result = Promise.all([p1,p2,p3])
console.log(result)
let p1 = new Promise((reslove,reject)=>{
reslove('OK')
})
let p2 = Promise.resolve('success')
let p3 = Promise.reject('error')
const result = Promise.all([p1,p2,p3])
console.log(result)
7.Promise.race方法:(Promise)=>{}
1.promise:包含n个promise的数组
说明:返回一个新的promise,第一个完成的promise的结果状态就是最终的结果状态
let p1 = new Promise((reslove,reject)=>{
setTimeout(()=>{
reslove('OK')
},1000)
})
let p2 = Promise.resolve('success')
let p3 = Promise.reject('error')
const result = Promise.race([p1,p2,p3])
console.log(result)
因为settimeout是一个异步调用,所以会先执行p2,则最先返回的是p2生成的promise的状态对象,则结果为p2
Promise中的几个问题
1.状态改变可以调用resolved rejected throw关键字改变promise对象的状态
2.当状态改变时可以执行多个回调,并且所有的回调都会执行
3.改变状态和指定回调函数谁先谁后
都有可能,正常情况下是先指定回调再改变状态,但也可以先改变状态,再指定回调
如何先改状态再执行回调
1.在执行器中直接调用reslove/reject(),即为同步任务时
2.延迟更长时间调用then()
当promise对象中封装的是一个异步任务时,会先指定回调后改变状态
什么时候拿到数据
1.如果先指定的回调,当状态发生改变时,回调函数就会调用,得到数据
2.如果是先改变的状态,当指定回调时,回调函数就会调用,得到数据
4.promise.then()返回的新的promise的结果状态由什么决定
1.由then指定的回调函数执行的结果决定
2.如果抛出了错误,则新的promise变为rejected,reason为抛出的异常
如果返回的是一个非promise的任意值,新的promise变为resolved,value为返回的值
如果返回的是另一个新promise,这个promise的结果就会变成新的promise的结果
5.promise如何串联多个任务
let p = new Promise((resolve,reject) => {
setTimeout(()=>{
resolve("ok")
},1000)
})
p.then(value=>{
return new Promise((resolve,reject)=>{
resolve('success')
})
}).then(value=>{
console.log(value)
}).then(value=>{
console.log(value)
})
因为promise.then()方法会返回一个promise对象,因为倒数第二个指定回调没有返回任何数据,则会返回undefined
6.promise的异常穿透
当promise的then链式调用时,可以在最后指定失败的回调
前面的任何操作出现了异常,都会传递到最后进行处理
7.中断promise链?
当使用promise的链式调用时,在中间中断,不在调用后面的后面的回调函数
办法:在回调函数中返回一个pendding状态的promise对象
自定义(手写)Prommise
还没写嘻嘻,以后写了再加个链接把
定义整体结构
async and await
async
async function main(){
return new Promise((resolve,reject)=>{
resolve('ok')
})
}
let result = main()
console.log(result)
1.如果返回值是一个非Promise类型的数据,他的值为改返回值
2.如果返回的是一个promise对象,其状态取决于返回的promise对象的状态
2.抛出异常其状态为rejected,值为抛出的值
await
1.await表达式的右边一般为promise对象,也可能为其他的值
2.如果表达式为promise对象,await返回的是promise成功的值
3.如果表达式是其他值,直接将此值作为await的返回值
注意:
await必须写在async函数中,但async函数中可以没有await
如果await的promise失败了,就会抛出异常,需要通过try catch来捕获处理
async function main(){
//右侧为promise的情况
let p = new Promise((resolve,reject)=>{
//resolve('OK')
resolve('Error')
})
let res = await p
console.log(res)
//右侧为其他类型的数据
let res2 = await 20
console.log(res2)
//如果promise为失败的情况
try{
let res3 = await p;
}catch(e){
console.log(e)
}
}
main();