Promise的正常用法
function xx(){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resovle('成功的輸出')
reject('失敗輸出')
},3000)
})
}
xx().then(fn1,s1).then(fn2,s2)//fn表示成功調用,s表示失敗調用
Promise的API
- Promise.resolve() 製造一個成功或失敗
- Promise.reject() 製造一個失敗
- Promise.all(數組) 等待全部成功,或者有一個失敗
- Promise.race(數組) 等待第一個狀態改變
- Promise.allSettled(數組) 等待全部狀態改變,API較新,瀏覽器支持的少
Promise的語法糖
Promise.then(fn1).catch(s1) 等於 Promise.then(fn1,s1)
Promise的面試題
頁面有兩個按鈕 A和B,以及一個輸入框,A按鈕點擊後發送一個請求,返回一個字符串A,B也發請求,但返回字符串B,返回後會把字符串賦值給輸入框,但是A,B發送的兩個請求返回的時間不同,點擊兩個按鈕的順序也不一定,B要比A先返回,而最終效果要求是輸入框字符的順序是AB。
primise.all()不好滿足這個需求。這需要用一個數組來記錄他們,當B請求回來時去數組中對比,順序不爲1,然後再等待,等到A請求回來後,輸出A然後再輸出B即可。
直接看實現的代碼吧:
<body>
<button id="b1">A</button>
<button id="b2">B</button>
<input id="input1" type="text">
</body>
let ajax1 = ()=>{
return new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve(1111)
},5000)
})
}
let ajax2 = ()=>{
return new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve(2222)
},3000)
})
}
let batai = []
let duiwu = []
let hi = () =>{
let lastN = batai[batai.length - 1][0]
let lastS = batai[batai.length - 1][1]
console.log(duiwu,'隊伍')
console.log(batai,'吧檯')
if(duiwu[0][0] === lastN) {
duiwu[0][1](lastS)
duiwu.shift()
batai.pop()
hi()
}
}
b1.onclick = ()=>{
const n = 1
ajax1().then(res=>{
batai.push([n, res])
hi()
})
duiwu.push([n, s=>{
input1.value = s
}])
}
b2.onclick = ()=>{
const n = 2
ajax2().then(res=>{
batai.push([n, res])
hi()
})
duiwu.push([n, s=>{
input1.value = s
}])
}
async await的基本用法
const fn = async ()=>{
const fn1 = await newPromise()
return fn1 + 1
}
相比較Promise,完全沒有鎖進,就像在寫同步代碼。
爲什麼async await函數前面要有一個async?
爲了兼容舊代碼,以前有人實現了與async/await功能相同的await函數,例如這樣:
await(newPromise())
所以爲了做區分,在函數前面增加async以示不同,沒有別的特殊含義。
優化async await錯誤處理
常見的錯誤處理方法 try/catch
let response
try{
response = await axios.get('/xx')
}.catch(err){
if(err.response){
console.log(err.response.states)
}
throw err
}
console.log(response)
這樣處理感覺不太好看,我們可以優化一下,結合Promise寫出如下代碼:
const response = await axios.get('/xx').then(null, err)
console.log(response)
response處理成功結果,then(null, err) 的err處理失敗結果。
async/await實際上就是Promise的語法糖。
async await面試題
let a = 0;
let test = async () => {
a = a + await 10;
console.log(a)
}
test()
console.log(++a)
請問log分別會輸出什麼?
答案:1,10
這裏考察的知識點:a + await 10 前面的a 是跟隨await一起異步確定的,還是a先確定值。
事實上在await前面的值都會同步執行,await後面的纔會異步執行,記住這點就很好理解了。
題目中雖然先log了++a,a值應該爲1。但是在test()函數中a + await 10 中的a在test()運行時就已經將值確定了,值爲0。
0 + 異步的await 10 等於10。