promise理解:
1,是js异步编程的新的解决方案
2,是一个构造函数
3,用来封装一个异步操作,并可以获得其结果
promise三个状态:
1,pendding 未确定
2,resolved 成功
3,rejected 失败
注:状态只能改变一次,成功数据称为value,失败称为reason
promise的基本使用
为什么要用Promise:
1.指定回调函数的方式灵活,可以在异步任务前指定也可以在异步任务后指定,而以前指定回调函数必须在异步任务开始前指定。
2.支持链式调用,可以解决回调地狱问题
3.回调地狱:回调函数嵌套调用,内层的回调函数需要的条件是外层异步执行的结果。不便于阅读还有异常处理,
4.解决方案。promise链式调用。
5.最佳解决方案,async/await(在程序员角度没有回调函数,编译后其实还是会有回调函数)
语法糖
p3.then(null,reason => {})相当于p3.catch( reason =>{} )
Promise.all()和Promise.race()
//all方法接收一个数组,数组元素是promise对象
//all方法返回一个Promise对象
const pall = Promise.all([p1,p2,p3])
pall.then(
values =>{},//如果全部执行成功,会返回一个数组,数组元素是三个promise对象resolve的值
reason =>{} //如果有一个失败,会返回失败的promise对象的reject的值
)
//race方法也是接收一个数组,数组元素也是promise对象
//race方法返回一个promise对象
const prace = Promise.race([p1,p2,p3])
prace.then(
value =>{},//第一个执行结束的promise如果是resolved状态,则调用该onResolved函数
reason =>{} //第一个执行结束的promise如果是rejected状态,则调用该onRejected函数
)
promise的几个关键问题
1.改变状态
(1)调用resolve() —>pendding会变成resolved
(2)调用reject() —>pendding会变成rejected
(3)抛出异常 —>pendding会变成rejected
2.指定多个回调函数(也就是多个then)都会调用
//多个then都会执行
p.then(
value=>{},
reason=>{}
)
p.then(
value=>{},
reason=>{}
)
3.(这个问题最重要也是最核心的!!!!!)promise.then()返回的promise的状态由then方法的两个回调函数的执行结果决定:
- 无论是onResolved()还是onRejected()执行成功,且没有返回值,那then返回的promise对象的状态就是resolved,value为undefinde。
- onResolved()或者onRejected()的返回值是一个非promise值,
那么then返回的promise的状态就是resolved,且value为return的值 - onResolved()或者onRejected()的return是一个promise,
那这个return的promise的结果就是then返回的promise的结果。 - 异常穿透:
如果then里面的onRejected回调函数没有定义,那么相当于定义了onRejected为
reason => {throw reason}。所以前面的promise对象如果状态为rejected,
而且then没有定义onRejected函数,那么reason => {throw reason}就会一直穿透下去 - 中断promise链
catch也会返回一个promise对象
中断方法:return一个pendding状态的promise对象
写法:return new Promise(()=>{}) - 改变promise和指定回调函数先后问题
(1)一般情况都是先指定回调函数再改变状态,因为promise执行器函数一般都是封装了异
步代码,所以会保存两个回调函数onResolved()和onRejected(),最后promise状
态改变后才决定调用那个回调函数。
(2)而如果先改变了状态,也就是promise执行器函数封装的是同步代码,那么在会直接
执行相对应状态的onResolved()和onRejected()
async
async用于修饰一个函数,函数的返回值为一个promise对象,该promise对象的状态由函数返回值决定,如果没有返回值并且没有抛出异常,那么相当于:return Promise.resolve(),如果函数抛出异常,则返回的promise对象状态为rejected。
await
1.await右侧的表达式一般为一个promise对象
2.如果修饰的不是promise对象,会返回该值本身
3.如果是promise对象,那么await的返回值是promise对象成功的值
4. 如果promise对象失败了,那么await会抛出这个错误的值 所以await要配合try catch使用 5.await必须写在async函数中,但是async函数可以没有await
6. await会阻塞进程,会暂停当前 async function 的执行,等待 Promise 处理完成。