async/await總結

2019第四發javascript

說明

一句話解釋:async 函數,就是 Generator 函數的語法糖。css

  • 創建在 promise 之上。因此,不能把它和回調函數搭配使用。但它會聲明一個異步函數,並隱式地返回一個Promise。所以能夠直接return變量,無需使用 Promise.resolve 進行轉換。
  • 和 promise 同樣,是非阻塞的。但不用寫 then 及其回調函數,這減小代碼行數,也避免了代碼嵌套。並且,全部異步調用,能夠寫在同一個代碼塊中,無需定義多餘的中間變量。
  • 它的最大價值在於,能夠使異步代碼,在形式上,更接近於同步代碼。
  • 它老是與 await 一塊兒使用的。而且,await 只能在 async 函數體內
  • await 是個運算符,用於組成表達式,它會阻塞後面的代碼。若是等到的是 Promise 對象,則獲得其 resolve 值。不然,會獲得一個表達式的運算結果。

開始

一個簡單的例子

JavaScript 代碼:java

const doSomethingAsync = () => {
    return new Promise((resolve) => {
        setTimeout(() => resolve('I did something'), 3000)
    })
}
 
const doSomething = async () => {
    console.log(await doSomethingAsync())
}
 
console.log('Before')
doSomething()
console.log('After')
複製代碼

結果

一切都是 promise

async關鍵字添加到任何函數,意味着該函數將返回一個Promise。git

const aFunction = async () => {
  return 'test'
}
aFunction().then(alert) // This will alert 'test'
複製代碼

而且與下面的代碼等價:github

const aFunction = async () => {
  return Promise.resolve('test')
}
aFunction().then(alert) // This will alert 'test'
複製代碼

代碼更易於閱讀 (重點看這個Demo)

每個步驟都須要以前每一個步驟的結果。編程

const getFirstUserData = () => {
  return fetch('/users.json') // get users list
    .then(response => response.json()) // parse JSON
    .then(users => users[0]) // pick first user
    .then(user => fetch(`/users/${user.name}`)) // get user data
    .then(userResponse => response.json()) // parse JSON
}
getFirstUserData()
複製代碼

而且與下面的代碼等價:json

const getFirstUserData = async () => {
  const response = await fetch('/users.json') // get users list
  const users = await response.json() // parse JSON
  const user = users[0] // pick first user
  const userResponse = await fetch(`/users/${user.name}`) // get user data
  const userData = await user.json() // parse JSON
  return userData
}
getFirstUserData()
複製代碼

連接多個 async(異步) 函數

每個步驟都須要以前每一個步驟的結果。promise

const promiseToDoSomething = () => {
    return new Promise(resolve => {
        setTimeout(() => resolve('I did something'), 10000)
    })
}
const watchOverSomeoneDoingSomething = async () => {
    const something = await promiseToDoSomething()
    return something + ' and I watched'
}
const watchOverSomeoneWatchingSomeoneDoingSomething = async () => {
    const something = await watchOverSomeoneDoingSomething()
    return something + ' and I watched as well'
}
watchOverSomeoneWatchingSomeoneDoingSomething().then((res) => {
    console.log(res)
})
//I did something and I watched and I watched as well
複製代碼

async/await中的錯誤處理

async經常使用異常處理

async function error() {
    try{
        //do something
    }catch(err){
        console.log(err)
    }
}
複製代碼

async中的錯誤處理

由於async的返回值也是個promise,跟promise的錯誤處理差很少。此外,async裏面throw Error 至關於返回Promise.reject異步

async function F(){
  throw new Error('test1')
}
var f=F();
f.catch(function(e){console.log(e)});
// Error:test1
複製代碼

await中的錯誤處理

在async中,await的錯誤至關於Promise.reject。async

async function F(){
  await Promise.reject('Error test1').catch(function(e){
     console.log(e)
  })
}
var f=F(); // Error:test1
複製代碼

await中的promise.reject必需要被捕獲

await若是返回的是reject狀態的promise,若是不被捕獲,就會中斷async函數的執行。

async function F(){
  await Promise.reject('Error test1');
  await 2
}
var f=F()
複製代碼

上述代碼中,前面的Promise.reject沒有被捕獲,因此不會執行await 2

支持

支持

常見問題

參考

  1. 總結一下ES6/ES7中promise、generator和async/await中的異常捕獲方法
  2. 用 async 和 await 編寫現代 JavaScript 異步代碼 – JavaScript 徹底手冊(2018版)
  3. 細說 async/await 相較於 Promise 的優點

總結

每個特性的出現,總有它的用途,而只有用了,才能更好地理解它。

JavaScript的異步編寫方式,從 回調函數 到 Promise、Generator 再到 Async/Await。表面上只是寫法的變化,但本質上則是語言層的一次次抽象。讓咱們能夠用更簡單的方式實現一樣的功能,而不須要去考慮代碼是如何執行的。

換句話說就是:異步編程的最高境界,就是根本不用關心它是否是異步。

相關文章
相關標籤/搜索