Promise的使用特點(diǎn)
1.Promise的狀態(tài)一旦改變就無法更改
new Promise(function(resolve,reject){
resolve();
reject();
}).then(function(res){
}).catch(function(){
})
只會(huì)執(zhí)行then中的方法,不會(huì)執(zhí)行catch中的
2.then方法的參數(shù)期望是函數(shù)杠步,傳入非函數(shù)則會(huì)發(fā)生值穿透
new Promise(function(resolve,reject){
resolve(123);
}).then('ASDASDAS').then(function(res){
console.log(res)
})
會(huì)執(zhí)行第二個(gè)then的回調(diào)
3.promise的回調(diào)是同步的蛹批,then是異步的
new Promise(function(resolve,reject){
console.log(1);
resolve();
}).then('ASDASDAS').then(function(res){
console.log(2)
})
console.log(3)
輸出結(jié)果為 1 3 2
4.鏈?zhǔn)秸{(diào)用then,上一個(gè)then的返回值是下一個(gè)then接收到的參數(shù)腐芍,如果拋出錯(cuò)誤,會(huì)返回一個(gè)狀態(tài)為reject的promise
new Promise(function(resolve,reject){
resolve();
}).then(function(){
return 123
}).then(function(last){
console.log(last)
})
打印123
new Promise(function(resolve,reject){
resolve();
}).then(function(){
throw new Error("I'm error ")
}).then(function(last){
console.log(last)
}).catch(function(error){
console.log("error:"+error)
})
打印Error: I'm error
如果是then的回調(diào)中return new Error() 還是要進(jìn)入下一個(gè)then中试躏,要throw拋出錯(cuò)誤才會(huì)進(jìn)入到catch中
5.如果返回的是promise 那么會(huì)等待promise的異步執(zhí)行猪勇,根據(jù)異步執(zhí)行的是resolve,還是reject再進(jìn)入then或者catch
new Promise(function(resolve,reject){
resolve();
}).then(function(){
return new Promise(function(resolve,reject){
setTimeout(function(){
resolve("go to then")
},3000)
})
}).then(function(last){
console.log(last)
}).catch(function(error){
console.log("error:"+error)
})
三秒之后打印:go to then
JS執(zhí)行順序
事件循環(huán)機(jī)制參考:譯文:JS事件循環(huán)機(jī)制(event loop)之宏任務(wù)椅您、微任務(wù)
1.每次執(zhí)行時(shí)先執(zhí)行主線程外冀,執(zhí)行主線程的過程中會(huì)碰到宏任務(wù)、微任務(wù)掀泳,各自放到各自的隊(duì)列當(dāng)中雪隧。
2.主線程執(zhí)行完畢之后執(zhí)行微任務(wù)
3.微任務(wù)執(zhí)行完畢之后將一個(gè)宏任務(wù)放到主線程中執(zhí)行
4.此時(shí)再根據(jù)主線程添加宏、微任務(wù)到對(duì)應(yīng)的任務(wù)隊(duì)列
//promise 為微任務(wù)
//setTimeout 為宏任務(wù)
setTimeout(function(){//setT1
console.log('set1')
//加到宏任務(wù)隊(duì)列
})
var p1 = new Promise(function(resolve,reject){
console.log('promise1')
resolve(2)
})
setTimeout(function(){//setT2
console.log('set2')
//加到宏任務(wù)隊(duì)列
})
p1.then(function(){
console.log('then1')
})
console.log(2)
promise1
2
then1
set1
set2
過程分析:
主線程:[p1=new Promise(),console.log(2)]
微任務(wù)隊(duì)列:[p1.then]
宏觀任務(wù)隊(duì)列:[setT1,setT2]
由于3.promise的回調(diào)是同步的员舵,then是異步的
所以promise的回調(diào)是放在主線程中執(zhí)行的脑沿,then放在微線程中
//promise 為微任務(wù)
//setTimeout 為宏任務(wù)
setTimeout(function(){//setT1
console.log('set1')
var p2= new Promise(function(resolve,reject){
console.log('promise2')
resolve(2)
}).then(function(){
console.log('then2')
})
//加到宏任務(wù)隊(duì)列
})
var p1 = new Promise(function(resolve,reject){
console.log('promise1')
resolve(2)
})
setTimeout(function(){//setT2
console.log('set2')
//加到宏任務(wù)隊(duì)列
})
p1.then(function(){
console.log('then1')
})
console.log(2)
promise1
2
then1
set1
promise2
then2
set2
過程分析:
主線程 [p1=new Promise,2]
微 [p1.then]
宏 [setT1,setT2]
setT添加到主線程中
主線程 [console.log('set1'),p2=new Promise]
微 [p2.then]
宏 [setT2]