ES7 非同步函式 (async await)
阿新 • • 發佈:2019-02-02
1.先說說Promise物件
Promise是ES6中處理非同步操作的一個新方式,Promise物件有三種狀態:Pending(進行中)、Resolved(已完成,又稱 Fulfilled)和 Rejected(已失敗),寫法如下:
//1)建立promise物件,建立後立刻執行
//接收一個函式作為引數,resolve、reject是Promise狀態發生變化時執行的函式,這裡由js引擎渲染出,不需要手動定義。
var promise = new Promise(function(resolve,reject){
setTimeout(()=>{
let num = parseInt(Math.random()*10 )
if(num%2){
resolve(0)
}else{
reject(1)
}
},500)
})
//2)狀態改變時的呼叫
promise.then(suc=>{
//執行上面的resolve()
console.log(`奇數;${suc}`)
},err=>{
//執行上面的reject()
console.log(`偶數;${err}`)
})
2.async function
async函式是ES7的內容,async函式可以看作是將非同步操作包裝成的一個 Promise 物件,而await命令就是內部then命令的語法糖,語法非常的簡單明瞭。 await 命令後面是一個promise物件,或者是其他非同步程序。await 表示式會暫停當前 async function 的執行,等待 Promise 處理完成。如果Promise 正常處理(fulfilled),其處理結果作為 await 表示式的值,繼續執行 async function;如果 Promise 處理異常,則異常值被丟擲,整個函式停止執行
//定義一個非同步函式
async getData(i){
let res;
try(){
//await 暫停當前函式的執行,直到非同步程序處理完成
res = await axios.get(`../../static/data${i}.json`)
}catch(e){
res = e
}
return res
}
async函式返回一個promise物件,函式內部return的值可以作為then方法回撥函式的引數。
getData(0).then(res=>{
console.log(res)
} )
3.併發問題
await關鍵字會暫停函式的執行,但不會阻塞程序
下面這種寫法,三個請求依次觸發
async function getNum_1() {
for(let i = 0; i < 3; i++){
console.log(`%c start${i}`, "color:green")
//暫停執行,等待結果
let res = await axios.get(`../../static/data${i}.json`)
//獲得結果,處理結果 並 進入下一次迴圈
console.log(res.data.msg)
}
}
正確的寫法是這樣:
function getNum_2(){
for(let i=0; i<3; i++){
//迴圈呼叫上文中的async函式,多個非同步函式併發,不會阻塞程序
this.getNum(i)
}
}
或者使用Promise物件的all方法
//1)使用map方法建立promise物件陣列
let promises = [0,1,2].map((i)=>{
return this.getNum(i) // 執行async函式,返回promise物件
})
//2)處理非同步結果
Promise.all(promises).then((res)=>{
//所有非同步方法完成後呼叫
console.log('done')
})