Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

await is only valid in async function - eval in async

I want to eval() some lines of code inside of async function. While the following code is ok,

async function foo()
{
  await foo1();
  await foo2();
}

the following throws an error: await is only valid in async function

let ctxScript = 'await foo1(); await foo2();';
async function foo()
{
  eval( ctxScript );
}

How could I handle this? My foo() should be async as it is Puppetteer controller function

like image 515
Randy Vogel Avatar asked May 17 '19 13:05

Randy Vogel


People also ask

How do you fix await is only valid in async?

The error "await is only valid in async functions and the top level bodies of modules" occurs when the await keyword is used inside of a function that was not marked as async . To solve the error, mark the directly enclosing function as async .

Can await only be used in async function?

The await operator is used to wait for a Promise . It can only be used inside an async function or a JavaScript module.

Is it mandatory to use await with async?

An async function without an await expression will run synchronously. The await expression causes async function execution to pause until a Promise is settled (that is, fulfilled or rejected), and to resume execution of the async function after fulfillment.

What happens if you dont use await in async function?

The call to the async method starts an asynchronous task. However, because no Await operator is applied, the program continues without waiting for the task to complete. In most cases, that behavior isn't expected.


2 Answers

foo() should not necessarily be async, as that has no effect on the execution context of eval. Instead, a possible solution is to wrap your ctxScript in a self-executing async function, like so: eval("(async () => {" + ctxScript + "})()")

like image 173
Ermir Avatar answered Sep 23 '22 22:09

Ermir


Here is another way without having to sleep or do anything complex.

In the code you pass to eval(), wrap your entire code in another async function and set it to some variable, for example, EVAL_ASYNC. Then after running eval(ctxScript), run that async function await EVAL_ASYNC.

let ctxScript = 'var EVAL_ASYNC = async function() {await foo1(); await foo2();}';
async function foo()
{
  eval( ctxScript );
  await EVAL_ASYNC();
}
like image 28
Joseph Shih Avatar answered Sep 20 '22 22:09

Joseph Shih