下面代碼打印結果是?
setTimeout(()=>{
console.log(1)
})
new Promise((resolve,reject)=>{
console.log(2)
resolve()
})
.then(()=>{
console.log(3)
})
new Promise((resolve,reject)=>{
console.log(4)
resolve()
})
.then(()=>{
console.log(5)
})
setTimeout(()=>{
console.log(6)
})
console.log(7)
/*
2
4
7
3
5
1
6
*/
*解析這道題之前我們先了解幾個知識點~~~~*
數據加載方案
- 同步加載
- 異步加載 : 事件 , 定時器 , ajax
js單線程語言
為什么是單線程語言?
dom操作
- 如果js是多線程語言,第一個線程執行把dom對象刪除,另一個線程執行把dom對象添加
同步代碼異步代碼加載順序 : event loop (事件循環)
- 先執行同步代碼,異步任務掛起
setTimeout(function(){
console.log(1);
},0)
console.log(2);
//執行結果 : 2 , 1 -->先執行console,log(2) setTimeout異步掛起
宏任務和微任務
-
宏任務一般是:包括整體代碼script,setTimeout,setInterval。
-
微任務:Promise,process.nextTick。
宏任務的異步 和微任務的異步同時都有 優先執行 微任務
了解了這些知識,我們回到第一題
1、首先:promise 的創建是同步的,then、catch是異步,所以先執行同步打印出2 4 7
2、異步的 1、3、5、6,進入事件隊列。
3、setTimeout 為宏任務,promise為微任務,先執行微任務,所以3、5先被打印出來,1、6后被打印出來
promise 承諾 是一個對象
異步代碼同步執行
1.三個狀態 : pending (進行時) resolve (成功狀態), reject(失敗的狀態).
2.使用時 需要實例化 new Promise()
3.Promise() 參數是一個回調函數
4.在回調函數中有兩個參數
resolve reject
5.promise返回值為promise
6.promise的方法
- .then()
兩個參數 都是回調函數
如果promise 執行resolve方法 執行為.then里面第一個回調
如果promise 執行reject方法 執行為.then里面第二個回調
- .catch()
當promise執行了reject方法的時候 執行的是.catch里面的回調
- .all()
- .race()
異步
js是單線程,防止被堵塞 node中將所有i/o變成異步
異步的過多嵌套會造成回調地獄
promise的鏈式調用可以解決回調地獄
async
- 可以修飾一個函數,被修飾的函數返回promise對象
- async 返回值可有也可以沒有,返回的是返回的數據就是then 接收的數據,不返回數據相當於undefined
async function text(){
return true
}
text()
.then((data)=>{
console.log("ok")
})
.catch((err)=>{
console.log("err")
})
await
- 在async函數內部使用,將promise變成同步
- await關鍵字后面跟Promise對象
//求和操作
function num1(){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(1)
},1000)
})
}
function num2(){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(2)
},500)
})
}
async function sum(){
let res1=await num1()
let res2=await num2()
reyturn res1 + res2
}
sum()
.then((data)=>{
console.log(data)
})
- 使用async函數可以讓代碼簡潔很多,不需要像Promise一樣需要些then,不需要寫匿名函數處理Promise的resolve值,也不需要定義多余的data變量,還避免了嵌套代碼。