按年来说是es2022,按迭代次数来说是es13,第13次。
2022年6月22日,第123届ecma大会批准了es2022语法规范,也就意味着它正式成为标准。那么来看看新特性之一 ------ top-level-await
之前
await命令只能出现在async函数内部,否则会报错
// 报错 await is only valid in async functions and the top level bodies of modules
await Promise.resolve(console.log(1))
上面代码中,await命令独立使用,没有放在async函数里面,就会报错。
在es2022之前,await关键字只能在async函数内容部使用。那么上面的例子,在es2022之前,就需要这样修改才行。
(async function() {
await Promise.resolve(console.log((1))
})()
再来,如果我们把上面这个代码放在单独的模块,在其他模块中引用,会出现什么情况呢。
// awaiting.js
let data
(async function() {
data = await Promise.resolve(console.log((1))
})()
export { data }
在另一个模块中去引入这个data
import { data } from './awaiting.js'
console.log(data) // undefined
setTimeout(() => {
console.log(data) // 1
}, 100)
上面的代码data的执行结果,完全取决于执行的时间,如果awaiting.js里面的异步操作没执行完,加载进来的data的值就是undefined
通过上面的代码可以看出,在另一个模块去引用一个异步模块导出的结果时候,其实并不能确保该异步结果的准确性,取决于被引用的异步模块是否执行完成。
现在
es2022的新特性
顶层 await,就可以解决上面代码中异步结果准确性的问题。顶层await处理所有里面的Promise,确保执行的有序性。
利用await解决模块异步加载的问题
await Promise.resolve(console.log(1)) // 不报错 输出1
// awaiting.js
let data = await Promise.resolve(1)
export { data }
import { data } from './awaiting.js'
console.log(data) // 1
总结
顶层 await命令有点像,交出代码的执行权给其他的模块加载,等异步操作完成后,再拿回执行权,继续向下执行。