Promise与JS引擎执行机制
一、Promise
ES6中提出的异步编程的新解决方案(在这之前单纯使用回调函数,易产生回调地狱)
1.Promise的状态与结果值
PromiseState为状态,初始为pending,在调用resolve后为resolved(fulfiled)表示成功,调用reject或throw错误后为rejected表示失败
PromiseResult为对象结果值,存放对象成功/失败的结果,也即resolve(xxx)或reject(err)中的xxx与err
2.than与catch
Promise中的excutor执行器函数,Promise(excutor){},也即如上图中的(res,rej)=>{...},它会在Promise内部立即调用,异步操作在执行器中执行,也就是说它里面的其他操作是同步的
Promise.then(onResolved,onRejected),onResolved与onRejected分别为成功与失败的回调,value与err为执行器中res与rej传递的值
Promsie.catch(onRejected)类似than,但只能只能传递失败的回调
3.Promise携带其他的方法
I.Promise.resolve(value),用于快速返回一个成功(value为非promise类型的对象时)
若传入的value为Promise对象,则参数的结果决定了resolve的结果
II.Promise.reject(reason),用于快速返回一个失败(无论是否为promise对象)
III.Promise.all([promise...]),传入一个promise数组,只有所有传入的promise都成功,才返回成功,其余返回第一个失败的promise
IV.Promise.race([promise..]),传入一个promise数组,第一个完成的promise结果状态就是最终的结果状态
4.Promise关键问题
I.可以指定多个回调
II.改变状态与指定回调的先后顺序
同步情况下,先改变状态(resolve/reject),再指定回调(.then),再得到数据(then中的操作)
当执行器中是异步任务(ajax/settimeout),先指定回调(.then),再改变状态(resolve/reject),再得到数据(then中的操作)
III.than方法返回结果
than方法返回promise对象,结果状态由回调函数执行的结果决定:
1.返回非promise,新promise为resolved,value为返回的值
2.返回另一个新promise,此promise 的结果结汇成为新promise的结果
3.throw抛出错误,则新promise为rejected,reason为抛出的错误
ps:无return则为undefined
IV.串联多个任务
由于then返回的也是一个promise,所以可以套娃
V.异常穿透与Promise链的中断
只需在最后指定异常
只能通过return一个pending状态的promise对象来中断
5.async与await
I.async函数返回值为promise对象,其结果由async函数执行的返回值决定
1.返回非promise
2.返回promise,由这个promise结果决定
3.抛出异常,则为rejected
II.await表达式右侧一般为promise对象,且必须写在async函数中
1.表达式为promise对象,返回promise成功的值
2.表达式为一般类型的数据
3.promise结果为失败,需要使用tyr{}catch(e){}捕获异常
III.async与await结合发送ajax
function sendAjax(url) { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.open('GET', url); xhr.send(); xhr.onreadystatechange = function() { if(xhr.readyState === 4) { if(xhr.status >= 200 && xhr.status < 300){ resolve(xhr.response); }else{ reject(xhr.status); } } } }) } // then sendAjax('https://api.apiopen.top/getJoke').then(value=>{ console.log(value); }, reason => { }) // async await async function sendmsg() { let daunzi = await sendAjax('https://api.apiopen.top/getJoke'); console.log(daunzi) } sendmsg();
二、JS引擎执行机制
这里只做粗略的解释,想要深入请自行查找相关资料
1.速成
1.JS判断代码是异步还是同步,同步在进入主线程,异步进入事件队列
2.异步任务根据情况分为微任务(promiese、muntation)与宏任务(定时器、ajax、dom事件回调)
3.Js执行主线程中的任务,直到主线程空闲
4.在取出第一个宏任务放到主线程之前,将所有微任务依次取出并执行
5.最后执行宏任务
2.实践
setTimeout(() => console.log('代码开始执行'),0) new Promise((resolve,reject) => { console.log('开始for循环'); for(let i=0;i<10000;i++){ i == 99 && resolve() } }).then(() => console.log('执行then函数')) console.log('代码执行结束'); //定时器异步,放入宏任务队列 //继续执行,输出:'开始for循环' //promise,放入微任务队列 //继续执行,输出:'代码执行结束' //执行promise.then,输出:'执行then函数' //最后执行定时器,输出:'代码开始执行'