Promise 與 async await 面試知識點

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。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章