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


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

先簡單介紹下async await:

  async/await是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函數中使用。

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

解決辦法,將箭頭函數聲明為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 的上下文 的具體意義。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM