我们都知道在异步编程中, await 只能在 aysnc function 里进行使用。await 提升了异步编程的体验,使我们能像同步函数那样处理异步函数。同时我们也会好奇 await 只能在 aysnc 中使用
ECMAScript 提案 Top-level await
允许开发者在 async 函数外使用 await 字段,目前已进入 tc39 Stage 3。
Top-level await 允许你将整个 JS 模块视为一个巨大的 async 函数,这样就可以直接在顶层使用 await,而不必用 async 函数包一层。
早在2020-08-11 node 发布 14.8.0 版本开始支持top-level await
1. 在引入top-level await之前
// ------ method.js
export function double(num) {
return num * 2;
}
export function square(num) {
return num * num;
}
// ------ middleware.js
import { double, square } from "./method.js";
let doubleOutput;
let squareOutput;
// IIFE
(async () => {
await requestData();
doubleOutput = double(10);
squareOutput = square(10);
})();
// 模拟接口请求
function requestData(delays = 1000) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(console.log("❤️"));
}, delays);
});
}
export { doubleOutput, squareOutput };
// ------ index.js
import { doubleOutput, squareOutput } from "./middleware.js";
console.log("doubleOutput-init", doubleOutput); // undefined
console.log("squareOutput-init", squareOutput); // undefined
setTimeout(() => console.log("doubleOutput-delay", doubleOutput), 2000); // 20
setTimeout(() => console.log("squareOutput-delay", squareOutput), 2000); // 100
### 2.使用 Export Promise 来代替初始化
// ------ method.js
export function double(num) {
return num * 2;
}
export function square(num) {
return num * num;
}
// ------ middleware.js
import { double, square } from "./method.js";
let doubleOutput;
let squareOutput;
// IIFE
export default (async () => {
await requestData();
doubleOutput = double(10);
squareOutput = square(10);
return { doubleOutput, squareOutput };
})();
// 模拟接口请求
function requestData(delays = 1000) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(console.log("❤️"));
}, delays);
});
}
export { doubleOutput, squareOutput };
// ------ index.js
import promise from "./middleware.js";
promise.then(({ doubleOutput, squareOutput }) => {
console.log("doubleOutput-delay", doubleOutput); // 20
console.log("squareOutput-delay", squareOutput); // 100
});
所有引用都要写成 promise 结构,十分不方便
3. 使用top-level await
// ------ method.js
export function double(num) {
return num * 2;
}
export function square(num) {
return num * num;
}
// ------ middleware.js
import { double, square } from "./method.js";
let doubleOutput;
let squareOutput;
// "plugins": ["@babel/plugin-syntax-top-level-await"]
await requestData();
doubleOutput = double(10);
squareOutput = square(10);
// 模拟接口请求
function requestData(delays = 1000) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(console.log("❤️"));
}, delays);
});
}
export { doubleOutput, squareOutput };
// ------ index.js
import { doubleOutput, squareOutput } from "./middleware.js";
console.log("doubleOutput-init", doubleOutput); // 20
console.log("squareOutput-init", squareOutput); // 100
4. 过去
当 async/await
首次引用时,尝试在 async
函数外部使用 await
的结果是产生 SyntaxError
。大多数开发者使用立即执行异步函数表达式的方式来使用该功能。
await Promise.resolve(console.log('🎉'));
// → SyntaxError: await is only valid in async function
(async function () {
await Promise.resolve(console.log('🎉'));
// → 🎉
})();
5. 现在
在 top-level await 的支持下,下面代码可以替换模块中常见代码
await Promise.resolve(console.log('🎉'));
// → 🎉
注意: top-level await 仅能工作在模块的顶层。在 class 代码块或非
async
函数不支持。
6. 何时使用
6.1 动态依赖导入
const strings = await import(`/i18n/${navigator.language}`);
这允许在模块的运行时环境中确认依赖项。
6.2 资源初始化
const connection = await dbConnector();
允许模块申请资源,同时也可以在模块不能使用时抛出错误。
6.3 依赖回退
let jQuery;
try {
jQuery = await import('https://cdn-a.example.com/jQuery');
} catch {
jQuery = await import('https://cdn-b.example.com/jQuery');
}
希望从 CDN A 加载 JavaScript 库,如果它加载失败,将加载 CDN B
结尾
top-level await 在某些特定场景有很方便的作用,但是目前这个一特性还没有很好的运用到生产代码中
本文整理自作者 Myles Borins 「Top-level await」,转载请注明来源链接
相关资源:
今天的文章top-level await分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/23453.html