JavaScript 使用 async 和 await 實現異步加載腳本

最近更新時間 2020-11-27 18:06:31

async 聲明的函數表示是異步執行的函數,async 函數中可使用 0 個或者多個 await 表達式,await 表達式會暫停整個 async 函數的執行進程並出讓其控制權,只有當其等待的代碼執行完後才繼續順序執行,一般用於 Ajax 請求可實現類似 Promise 的功能。

最簡單的定義如下所示:

async function asyncCall() {
  #await  ajax1
  #await  ajax2
  #response
}

asyncCall()
VM91:2 Uncaught SyntaxError: await is only valid in async function

await 關鍵字只能位於 async 函數內否則會拋出如上語法錯誤。

async 函數一定會返回一個 Promise 對象,如果返回值不是 Promise 對象,會被自動包裝到一個 Promise 對象中,如下所示:

async function asyncCall() {
  return 1
}

console.log(asyncCall())

Promise {: 1}
__proto__: Promise
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: 1

//等價於 

async function asyncCall() {
  return Promise.resolve(1)
}



async function asyncCall() {
  await 1
}

console.log(asyncCall())

Promise {}
__proto__: Promise
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: undefined

//等價於 

async function asyncCall() {
  Promise.resolve(1).then(() => undefined)
}

在 await 表達式之後的代碼可以被認為是存在在鏈式調用的 then 回調中,多個 await 表達式都將加入鏈式調用的 then 回調中,返回值將作為最後一個 then 回調的返回值。

簡單實現異步加載腳本

如果項目中需要多個 JS 文件,執行語句依賴於所有 JS 都加載完成,下面的方法將實現異步執行多個 JS 的文件加載,加載完成後執行邏輯代碼。

const lazyLoad = async () => {

  await import('zepto.min.js');
  await import('js1.min.js');
  await import('js2.min.js');

  //執行語句
}

lazyLoad()

兼容性

瀏覽器 支持版本
Chrome 55
Edge 15
Firefox 52
Internet Explorer 不支持
Opera 42
Safari 10.1
Android webview 55
Chrome for Android 55
Safari on iOS 10.3
Node.js 7.6.0
rss_feed