await is only valid in async function

后端 未结 9 1451
青春惊慌失措
青春惊慌失措 2020-11-22 06:53

I wrote this code in lib/helper.js

var myfunction = async function(x,y) {
   ....
   return [variableA, variableB]
}
exports.myfunction = myfunct         


        
相关标签:
9条回答
  • 2020-11-22 07:14

    I had the same problem and the following block of code was giving the same error message:

    repositories.forEach( repo => {
            const commits = await getCommits(repo);
            displayCommit(commits);
    });
    

    The problem is that the method getCommits() was async but I was passing it the argument repo which was also produced by a Promise. So, I had to add the word async to it like this: async(repo) and it started working:

    repositories.forEach( async(repo) => {
            const commits = await getCommits(repo);
            displayCommit(commits);
    });
    
    0 讨论(0)
  • 2020-11-22 07:17

    The current implementation of async / await only supports the await keyword inside of async functions Change your start function signature so you can use await inside start.

     var start = async function(a, b) {
    
     }
    

    For those interested, the proposal for top-level await is currently in Stage 2: https://github.com/tc39/proposal-top-level-await

    0 讨论(0)
  • 2020-11-22 07:22

    To use await, its executing context needs to be async in nature

    As it said, you need to define the nature of your executing context where you are willing to await a task before anything.

    Just put async before the fn declaration in which your async task will execute.

    var start = async function(a, b) { 
      // Your async task will execute with await
      await foo()
      console.log('I will execute after foo get either resolved/rejected')
    }
    

    Explanation:

    In your question, you are importing a method which is asynchronous in nature and will execute in parallel. But where you are trying to execute that async method is inside a different execution context which you need to define async to use await.

     var helper = require('./helper.js');   
     var start = async function(a,b){
         ....
         const result = await helper.myfunction('test','test');
     }
     exports.start = start;
    

    Wondering what's going under the hood

    await consumes promise/future / task-returning methods/functions and async marks a method/function as capable of using await.

    Also if you are familiar with promises, await is actually doing the same process of promise/resolve. Creating a chain of promise and executes you next task in resolve callback.

    For more info you can refer to MDN DOCS.

    0 讨论(0)
  • 2020-11-22 07:24

    When I got this error, it turned out I had a call to the map function inside my "async" function, so this error message was actually referring to the map function not being marked as "async". I got around this issue by taking the "await" call out of the map function and coming up with some other way of getting the expected behavior.

    var myfunction = async function(x,y) {
        ....
        someArray.map(someVariable => { // <- This was the function giving the error
            return await someFunction(someVariable);
        });
    }
    
    0 讨论(0)
  • 2020-11-22 07:24

    "await is only valid in async function"

    But why? 'await' explicitly turns an async call into a synchronous call, and therefore the caller cannot be async (or asyncable) - at least, not because of the call being made at 'await'.

    0 讨论(0)
  • 2020-11-22 07:30

    The error is not refering to myfunction but to start.

    async function start() {
       ....
    
       const result = await helper.myfunction('test', 'test');
    }
    

    // My function
    const myfunction = async function(x, y) {
      return [
        x,
        y,
      ];
    }
    
    // Start function
    const start = async function(a, b) {
      const result = await myfunction('test', 'test');
      
      console.log(result);
    }
    
    // Call start
    start();



    I use the opportunity of this question to advise you about an known anti pattern using await which is : return await.


    WRONG

    async function myfunction() {
      console.log('Inside of myfunction');
    }
    
    // Here we wait for the myfunction to finish
    // and then returns a promise that'll be waited for aswell
    // It's useless to wait the myfunction to finish before to return
    // we can simply returns a promise that will be resolved later
    
    // useless async here
    async function start() {
      // useless await here
      return await myfunction();
    }
    
    // Call start
    (async() => {
      console.log('before start');
    
      await start();
      
      console.log('after start');
    })();


    CORRECT

    async function myfunction() {
      console.log('Inside of myfunction');
    }
    
    // Here we wait for the myfunction to finish
    // and then returns a promise that'll be waited for aswell
    // It's useless to wait the myfunction to finish before to return
    // we can simply returns a promise that will be resolved later
    
    // Also point that we don't use async keyword on the function because
    // we can simply returns the promise returned by myfunction
    function start() {
      return myfunction();
    }
    
    // Call start
    (async() => {
      console.log('before start');
    
      await start();
      
      console.log('after start');
    })();


    Also, know that there is a special case where return await is correct and important : (using try/catch)

    Are there performance concerns with `return await`?

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