JavaScript 使用 async 和 await 实现异步加载脚本

Lasted 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