1. 程式人生 > >前端專案中常用es6知識總結 -- Async、Await讓非同步美如畫

前端專案中常用es6知識總結 -- Async、Await讓非同步美如畫

專案開發中一些常用的es6知識,主要是為以後分享小程式開發、node+koa專案開發以及vueSSR(vue服務端渲染)做個前置鋪墊。

專案開發常用es6介紹

  • 1、塊級作用域 let const

  • 2、箭頭函式及this指向

  • 3、promise、asnyc await語法

  • 4、模組化 module export和import

  • 5、解構賦值、字串模板

  • ……

asnyc await

首先看一段程式碼示例:

var promise = () => new Promise((resolve, reject) => {
    setTimeout(() 
=> { resolve("我是資料") }, 1000) }) var func = async () => { var data = await promise(); //await用於等待promise函式的結果 console.log(data) return data // 一秒後打印出 “我是資料” } console.log(func()) // Promise {<pending>} 即func函式的返回值是一個Promise //呼叫就立即返回一個狀態為pending的Promise,一秒後變成resolve狀態

由此可以看出:

1、async表示函式裡有非同步操作

2、await表示緊跟在後面的表示式需要等待結果(阻塞程式碼往下執行)

3、async函式的返回值是 Promise 物件

既然async函式的返回值是 Promise 物件,那就可以使用then方法來接收resolve傳遞過來的引數,上述程式碼也可以這樣實現:

var promise = () => new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("我是資料")
    }, 1000)
}) var func = async () => {
    
var data = await promise(); //await用於等待promise函式的結果 console.log(data) return data // 一秒後打印出 “我是資料” } // console.log(func()) // Promise {<pending>} 即func函式的返回值是一個Promise //呼叫就立即返回一個狀態為pending的Promise,一秒後變成resolve狀態 func().then((data) => { console.log(data) //我是資料 })

所以,再追加一條:

4、async函式內部return語句的返回值,就是then方法回撥函式的引數。

也就意味著如果async函式內部沒有寫return語句,then方法回撥函式的引數值就是undefiend。

錯誤處理

如果await後面的非同步操作出錯,那麼等同於async函式返回的 Promise 物件被reject。同樣如果有多個await,其中一個出錯也會將Promise 物件的狀態置為reject。所以在進行錯誤處理的時候所以最好把await命令放在try...catch程式碼塊中。

var promise = (data, ms) => new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(data)
    }, ms)
}) var func = async () => {
    try {
        var data1 = await promise("資料1", 1000);
        console.log(data1) var data2 = await promise("資料2", 1000);
        console.log(data2) var data3 = await promise("資料3", 1000);
        console.log(data3)
    } catch (error) {
        console.error(err)
    }
}
func() //每隔一秒依次列印 資料1 資料2 資料3
//如果希望當前一個非同步失敗不影響後面的非同步操作執行可以將其單獨放在try{}catch(){}語句裡

注意:多個await命令後面的非同步操作,如果不存在相互依賴關係,最好讓它們同時觸發。因為當多個await後面的非同步操作是一個接一個的完成的,這樣會比較耗時,如果將他們同時觸發則會大大縮短程式執行的時間。比如上述程式碼可以按照如下寫法同時執行:

var promise = (data, ms) => new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(data)
    }, ms)
})
var func = async () => {
    try {
        //寫法1
        var data = await Promise.all([promise("資料1", 1000), promise("資料2", 1000), promise("資料3", 1000)]);
        console.log(data) //["資料1", "資料2", "資料3"]

        //寫法2
        var datafn1 = promise("資料1", 1000);
        var datafn2 = promise("資料2", 1000);
        var datafn3 = promise("資料3", 1000);
        var data1 = await datafn1;
        var data2 = await datafn2;
        var data3 = await datafn3;
        console.log(data1, data2, data3) //資料1 資料2 資料3
    } catch (error) {
        console.error(error)
    }
}
func()

上面兩種寫法,都是同時觸發,這樣就會縮短程式的執行時間。 注意:正常情況下,await命令後面是一個 Promise 物件,返回該物件的結果。如果不是 Promise 物件,就直接返回對應的值。

async function func() {
    // return 123;
    // return await 123;
    return await Promise.resolve(123)
}
func().then(function(data) {
    console.log(data) //123
})

當然:如果func函式內部沒有寫return,then方法的回撥函式裡data就等於undefined