Using await outside of an async function

前端 未结 5 531
野性不改
野性不改 2020-11-27 15:26

I was attempting to chain two async functions together, because the first had a conditional return parameter that caused the second to either run, or exit the module. Howeve

相关标签:
5条回答
  • 2020-11-27 15:33

    There is always this of course:

    (async () => {
        await ...
    
        // all of the script.... 
    
    })();
    // nothing else
    

    This makes a quick function with async where you can use await. It saves you the need to make an async function which is great! //credits Silve2611

    0 讨论(0)
  • 2020-11-27 15:34

    you can do top level await since typescript 3.8
    https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#-top-level-await
    From the post:
    This is because previously in JavaScript (along with most other languages with a similar feature), await was only allowed within the body of an async function. However, with top-level await, we can use await at the top level of a module.

    const response = await fetch("...");
    const greeting = await response.text();
    console.log(greeting);
    
    // Make sure we're a module
    export {};
    

    Note there’s a subtlety: top-level await only works at the top level of a module, and files are only considered modules when TypeScript finds an import or an export. In some basic cases, you might need to write out export {} as some boilerplate to make sure of this.

    Top level await may not work in all environments where you might expect at this point. Currently, you can only use top level await when the target compiler option is es2017 or above, and module is esnext or system. Support within several environments and bundlers may be limited or may require enabling experimental support.

    0 讨论(0)
  • 2020-11-27 15:46

    As of Node.js 14.3.0 the top-level await is supported.

    Required flag: --experimental-top-level-await.

    Further details: https://v8.dev/features/top-level-await

    0 讨论(0)
  • 2020-11-27 15:49

    Top level await is not supported. There are a few discussions by the standards committee on why this is, such as this Github issue.

    There's also a thinkpiece on Github about why top level await is a bad idea. Specifically he suggests that if you have code like this:

    // data.js
    const data = await fetch( '/data.json' );
    export default data;
    

    Now any file that imports data.js won't execute until the fetch completes, so all of your module loading is now blocked. This makes it very difficult to reason about app module order, since we're used to top level Javascript executing synchronously and predictably. If this were allowed, knowing when a function gets defined becomes tricky.

    My perspective is that it's bad practice for your module to have side effects simply by loading it. That means any consumer of your module will get side effects simply by requiring your module. This badly limits where your module can be used. A top level await probably means you're reading from some API or calling to some service at load time. Instead you should just export async functions that consumers can use at their own pace.

    0 讨论(0)
  • 2020-11-27 15:51

    Even better is to put additional semicolon in front of the code block

    ;(async () => {
        await ...
    })();
    

    This prevents auto-formatter (e.g. in vscode) to move the first parenthese to the end of the previous line.

    The problem can be demonstrated on the following example:

    const add = x => y => x+y
    const increment = add(1)
    (async () => {
        await ...
    })();
    

    Without the semicolon, this will be re-formatted as:

    const add = x => y => x+y
    const increment = add(1)(async () => {
      await Promise(1)
    })()
    

    which obviously is wrong because it assigns the async function as the y parameter and tries to call a function from the result (which is actually a weird string '1async () => {...}')

    0 讨论(0)
提交回复
热议问题