Javascript 等待仅在异步函数-eval中有效

Javascript 等待仅在异步函数-eval中有效,javascript,node.js,asynchronous,eval,Javascript,Node.js,Asynchronous,Eval,我想eval()异步函数内部的一些代码行。虽然以下代码正常 async function foo() { await foo1(); await foo2(); } 下面抛出一个错误:wait仅在异步函数中有效 let ctxScript = 'await foo1(); await foo2();'; async function foo() { eval( ctxScript ); } 我该怎么办? My foo()应该是异步的,因为它是puppeter控制器函数foo()不

我想eval()异步函数内部的一些代码行。虽然以下代码正常

async function foo()
{
  await foo1();
  await foo2();
}
下面抛出一个错误:wait仅在异步函数中有效

let ctxScript = 'await foo1(); await foo2();';
async function foo()
{
  eval( ctxScript );
}
我该怎么办?
My foo()应该是异步的,因为它是puppeter控制器函数

foo()
不一定是异步的,因为这对
eval
的执行上下文没有影响。相反,一个可能的解决方案是将ctxScript封装在一个自动执行的异步函数中,如下所示:
eval(((async()=>{“+ctxScript+”})()”)

如果您想在某个更大的函数中动态调用某些异步代码,那么您可以提供一个为您执行此操作的回调。通过这种方式,您可以使用不同的额外功能调用函数,方法是为其提供不同的回调函数以执行:

//一些示例异步函数
var resolveAfter2Seconds=函数(){
log(“启动慢承诺->”;
返回新承诺(解决=>{
setTimeout(函数(){
决心(“缓慢”);
控制台日志(“”);
返回新承诺(解决=>{
setTimeout(函数(){
决心(“快速”);

console.log(“最终使用了Ermir的答案:

let ctxScript = '(async () => {await foo1();await foo2();is_script_ended = true; })();';

async function foo()
{
  // a lot of code
  is_script_ended = false;
  eval( ctxScript );
  while(!is_script_ended){ await sleep(1000); }
  // a lot of code
}

如果您希望能够等待评估,您可以使用:

await Object.getPrototypeOf(异步函数(){}).constructor(“此处的代码”)();
这使用了
AsyncFunction
构造函数。MDN描述了使用它和使用
eval
之间的区别:

注意:使用AsyncFunction构造函数创建的异步函数不会为其创建上下文创建闭包;它们总是在全局范围内创建的

运行它们时,它们将只能访问自己的局部变量和全局变量,而不能访问调用AsyncFunction构造函数的作用域中的变量

这不同于对异步函数表达式的代码使用eval

这意味着,如果您有希望被评估代码能够访问的变量,则需要将它们添加到
globalThis

const testVar=“Hello world”;
globalThis[“testVar”]=testVar;
const result=await Object.getPrototypeOf(异步函数(){}).constructor(`
log(testVar);
等待myAsyncFunc();
返回testVar;
`)();
//结果将是“你好,世界”
删除globalThis[“testVar”];

这里是另一种不用睡觉或做任何复杂事情的方法

在传递给
eval()
的代码中,将整个代码包装在另一个异步函数中,并将其设置为某个变量,例如
eval\u async
。然后在运行
eval(ctxScript)
后,运行该异步函数
等待eval\u async

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

退一步-为什么要
eval
代码?如果你告诉我们真正的问题,可能会发现我希望根据不同的条件执行不同的操作。我的async foo()很大,但只有我希望eval()执行的小部分代码是不同的。您已经可以执行不同的函数,而不需要
eval
-
if
例如,或者调用一个完全不同的函数、多态性、使用功能设置查找表等等。好的,我的X问题是我想在函数内部使用一些不同的代码,应该是异步的,最好的Y是什么要做到这一点?将所有的async()代码移动到Include中,就像回答#1中所说的那样?为什么在询问eval时总是要有人说不要使用eval?回答这个问题,它有合法的用例。我的foo()应该是异步的,因为它是一个puppetter控制器函数。我的观点是is async与否与eval中的代码是否在异步执行上下文中没有关系。因此我的答案是。因此,wait在eval()内部、异步函数内部不起作用。从上面的注释来看,在这里使用eval可能不是解决问题的最佳方案,因为它有很多缺点(较慢,不同的执行上下文,代码注入的风险)现在,这只是一个快速补丁,可以看到、理解并接受所有风险。但这是我第一次使用node.js和async,所以我还不知道更好的方法。对于这个伟大的示例,请想象一下,我在async函数foo()的定义中有一些对象,它是在调用函数foo()时,在调用某个代码之后和回调之前创建的,并具有数千种不同的双重等待(现在存储到文件中)ths没有解释如何从异步中获取表达式值,只解释如何调用函数later@wowow有什么问题吗?
const result=await callback()
将获得该值。我认为不需要明确说明,因为这样做的方式没有改变。我重点介绍了如何避免
eval
。在代码中睡眠从来都不是一个好主意。嘿,如果你的eval脚本失败,那么它将永远休眠,直到你重新启动系统。如果你真的想使用sleep,也许将所有内容都包装在一个try-catch中,这样如果代码中断,您的睡眠就会停止。类似于
try{eval(ctxScript)}catch(){is_script_end=true}
您是否在异步函数中运行该示例?该示例创建了一个异步函数,并使用wait调用它,因此您需要在异步函数中使用它。