原文首發地址: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();
運行結果:函數
至此,問題解決。
a
wait
必須在async函數的上下文中。出處
上下文,英文context,其完整意思應當是concatenate-text,聯繫文本,編程中翻譯爲「引用池」或者「引用區」更加恰當
先舉個例子:
③.小明說:重啓試試
單從這句話咱們不能知道重啓什麼、爲何小明要說這句話(可能你以爲是電腦)、對誰說的這句話
②.小紅說對小明說她微信出來不了輸入法
這就是小明爲何說這句話的上文(背景),這時候才能知道小明說的重啓是微信程序or手機(真不是電腦)
①.小紅和小明躺在牀上玩手機
這句也是背景,可是卻不能成爲3的上文,由於「躺牀上」並非「重啓試試」的緣由(或者說背景)
函數調用會在內存造成一個"調用記錄",又稱"調用幀"(call frame),保存調用位置和內部變量等信息
我的理解:上文指出了環境、背景。
拿本文中的第一段錯誤代碼來講,await的上文是一個普通箭頭函數,因此使用await會報錯,由於編譯器在執行到await時,當前調用幀是箭頭函數而不是外層的start,因此此時的await就像:小明和小紅躺在牀上 小明說「重啓試試」 ,是無心義(Unexpected identifier)的。
這時候談談下文,接上面的例子
④.小紅重啓了手機
這時候④就是③的下文
須要注意的是,上下文是一個總體,上面我把它分開只是爲了理解,實際過程當中,不存在單獨的上文和下文,因此這是await 必須在async 的上下文 的具體意義。