We all know that in asynchronous programming, await can only be used in aysnc function. Await improves the experience of asynchronous programming and allows us to handle asynchronous functions as synchronous functions. We also wonder that await can only be used in AYSNC

The ECMAScript proposal top-level await allows developers to use await fields outside of async functions and is currently in TC39 Stage 3.

Top-level await allows you to treat the entire JS module as one giant async function, so you can use await directly at the Top level instead of wrapping async functions with a layer.

Support for top-level await began as early as the release of version 14.8.0 for 2020-08-11 Node

1. Before introducing 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); }) ();// Simulate the interface request
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

Copy the code
// ------ 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 }; }) ();// Simulate the interface request
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
});

Copy the code

All references have to be written in the inconvenient promise structure

3. Use 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);

// Simulate the interface request
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

Copy the code

4. In the past

When async/await is first referenced, an attempt to use await outside an async function results in a SyntaxError. Most developers use this feature by executing asynchronous function expressions immediately.

await Promise.resolve(console.log('🎉'));
// → SyntaxError: await is only valid in async function
(async function () {
  await Promise.resolve(console.log('🎉'));
  / / > 🎉}) ();Copy the code

Now 5.

With top-level await support, the following code can replace common code in modules

await Promise.resolve(console.log('🎉'));
/ / > 🎉
Copy the code

Note: Top-level await works only at the top level of the module. Not supported in class code blocks or non-async functions.

6. When to use

Refer to spec Proposal Repository

6.1 Dynamic Dependency Import

const strings = await import(`/i18n/${navigator.language}`);
Copy the code

This allows dependencies to be validated in the module’s runtime environment.

6.2 Resource Initialization

const connection = await dbConnector();
Copy the code

Allows a module to request resources and also throws an error if the module is not available.

6.3 Dependency Rollback

let jQuery;
try {
  jQuery = await import('https://cdn-a.example.com/jQuery');
} catch {
  jQuery = await import('https://cdn-b.example.com/jQuery');
}
Copy the code

You want to load the JavaScript library from CDN A, and if it fails to load, CDN B will be loaded

At the end

Top-level await is useful in certain scenarios, but it is not currently used in production code

This article is from Myles Borins “top-level await”

V8. Dev/features/to…

Related resources:

  • @babel/plugin-syntax-top-level-await
  • Github.com/tc39/propos…