從async await 報錯Unexpected identifier 談談對上下文的理解

原文首發地址:http://www.cnblogs.com/lonhon/p/7518231.htmlhtml

先簡單介紹下async await:node

  async/await是ES6推出的異步處理方案,目的也很明確:更好的實現異步編程。   詳細見阮大神 ES6入門es6

如今說說實踐中遇到的問題:使用await報錯Unexpected identifier編程

先上代碼:微信

var sleep = function (time) {
    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            resolve(('999'));
        }, time);
    })
};
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
var start = async function(){
    arr.forEach(()=>{
        console.log( await sleep(2000) )
    })
}
start();

 

 

在循環中使用sleep方法,這時候報錯:Unexpected identifier異步

 

緣由:經過查資料發現一句話 await必須在async函數的上下文中。(後面重點講)經過我的理解的這句話就是await只能在async函數中使用。async

以上面的代碼爲例子,雖然最外層start函數是經過async聲明的,在start函數體內部的箭頭函數中使用了await,而該箭頭函數是一個普通函數,因此await的上文是一個普通函數,最終致使報錯。ide

解決辦法,將箭頭函數聲明爲async函數,代碼以下:異步編程

var sleep = function (time) {
    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            resolve(console.log('999'));
        }, time);
    })
};
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
var start = function(){
    arr.forEach(async ()=>{
        await sleep(2000)
    })
}
start();

運行結果:函數

 

至此,問題解決。

 

 

await必須在async函數的上下文中。出處

上下文,英文context,其完整意思應當是concatenate-text,聯繫文本,編程中翻譯爲「引用池」或者「引用區」更加恰當

先舉個例子:

③.小明說:重啓試試

單從這句話咱們不能知道重啓什麼、爲何小明要說這句話(可能你以爲是電腦)、對誰說的這句話

②.小紅說對小明說她微信出來不了輸入法

這就是小明爲何說這句話的上文(背景),這時候才能知道小明說的重啓是微信程序or手機(真不是電腦)

①.小紅和小明躺在牀上玩手機

這句也是背景,可是卻不能成爲3的上文,由於「躺牀上」並非「重啓試試」的緣由(或者說背景)

 

函數調用會在內存造成一個"調用記錄",又稱"調用幀"(call frame),保存調用位置和內部變量等信息

我的理解:上文指出了環境、背景。

拿本文中的第一段錯誤代碼來講,await的上文是一個普通箭頭函數,因此使用await會報錯,由於編譯器在執行到await時,當前調用幀是箭頭函數而不是外層的start,因此此時的await就像:小明和小紅躺在牀上 小明說「重啓試試」  ,是無心義(Unexpected identifier)的。

這時候談談下文,接上面的例子

④.小紅重啓了手機

這時候④就是③的下文

 

須要注意的是,上下文是一個總體,上面我把它分開只是爲了理解,實際過程當中,不存在單獨的上文和下文,因此這是await 必須在async 的上下文 的具體意義。

相關文章
相關標籤/搜索