【问题标题】:How to use async await with eval() function in javascript?如何在javascript中使用带有eval()函数的异步等待?
【发布时间】:2020-11-11 18:13:38
【问题描述】:

我正在使用 eval 函数来评估字符串,并且我正在对 eval 函数应用 await 以便获得所有值。但是等待不起作用

我的代码是这样的:-

if (matchCard.card.status != "notstarted") {
    return new Promise((resolve) => {
        questionSetObj.forEach(async ([key, value], index) => {
            let thisVal = await eval(value.functionName)(value, key);
            console.log("thisVal....", thisVal)
            if (thisVal) {
                if (thisVal[key] != "NotFound") answerSet[key] = thisVal[key]
            }
            console.log("answerSet", answerSet);
            answerSetArray.push(answerSet);
            if (index === questionSetObj.length - 1) resolve(answerSetArray);
        });
    })
}

上述函数中用到的变量,它们的值:-

变量值 = { teamTwoId: 'wi', matchId: 'iccrzt20_2020_vg_g7', 问题:'哪支球队会赢得比赛?', functionName: 'matchWinnerTeam', 选项:{选项2:'西印度群岛',选项1:'阿富汗'}, teamOneId:'afg' }

在值 obj 中,函数名称:'matchWinnerTeam'。 matchWinnerTeam() 是一个评估问题答案的函数。

var key = Q1

同样,我有 5 个类似这样的问题集。

问题陈述:-

我的 answerSet 对象值应该返回如下值:- 答案集 = { Q5:'选项2', Q3:'选项2', Q2:'选项2', Q4:'选项1', Q1:'选项2' } 但实际上,每当我在节点 js 服务器上运行此函数时,它都会返回类似这样的值:-
{ Q5:'选项2', Q3:'选项2', }, { Q1:'选项2', Q4:'选项2', } .....等等。

我发现的问题是 eval 函数必须等到它返回从 Q1 到 Q5 的所有值,但 await 在 eval() 上不起作用。它评估两个问题的答案并返回这两个值,而不是等待其余 3 个答案得到评估。

那么我可以像这样在 eval() 上使用 await 吗,或者会有一些替代方法来执行此任务?

请帮忙。谢谢你

【问题讨论】:

  • 请避免使用eval。您只能使用它来按名称获取函数 - 您可以传递一个对象,您可以在其中按名称或更好的方式获取函数,questionSetObj 可以直接使用这些函数,因此您不需要 eval 他们但是执行它们
  • 你只能等待一个promise,eval 可以返回一个promise,这取决于你正在评估什么。
  • @VLAZ 基本上你是说我可以像这样直接使用 (value.functionName)(value, key);不需要评估。
  • @AmanSingh 仅当您直接将函数作为引用传递时,而不是在传递函数名称时。所以你需要[{f: function() { console.log("one"); } }, {f: function() { console.log("two") } }] 而不是[{functionName: "functionOne" }, { ffunctionName: "functionTwp" }]

标签: javascript node.js


【解决方案1】:

好吧,我不认为使用 eval 是邪恶的,当然当你知道你在做什么的时候!据我了解,就您而言,您想等待 eval 完成。因此,您可以创建 promise 包装器并将 resolve 放入您的 eval 代码中,即:

let toeval = `
  // Iteration number
  let i = 100;

  // Finish function
  const finish = () => {
    // Resolve
    resolve('This is data from eval');
  }

  // Delay function
  const delay = () => {
    setTimeout(() => {
      if(i) {
        i--;
        delay();
      } else finish();
    }, 10);
  }

  // Run delay
  delay();
`;

// Wait for eval wrapper
const waitEval = (ev) => {
  return new Promise((resolve, reject) => {
    eval(ev);
  });
};
                     
// Main function
(async () => {
  // Start message
  console.log(`Starting and waiting for eval to complete...`);
  
  // Run and wait for eval
  const x = await waitEval(toeval);
  console.log(`Result from eval: ${x}`);
  
  // Continue
  console.log(`Finished! Continue program...`);
})();

但请记住,如果您想以更安全的方式执行上述操作,请使用new Function 而不是eval

let toeval = `
  // Iteration number
  let i = 100;

  // Finish function
  const finish = () => {
    // Resolve
    resolve('This is data from eval');
  }

  // Delay function
  const delay = () => {
    setTimeout(() => {
      if(i) {
        i--;
        delay();
      } else finish();
    }, 10);
  }

  // Run delay
  delay();
`;

// Wait for new Function wrapper
const waitFn = (ev) => {
  return new Promise((resolve, reject) => {
    new Function('resolve', ev)(resolve);
  });
};
                     
// Main function
(async () => {
  // Start message
  console.log(`Starting and waiting for eval to complete...`);
  
  // Run and wait for eval
  const x = await waitFn(toeval);
  console.log(`Result from eval: ${x}`);
  
  // Continue
  console.log(`Finished!`);
})();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-16
    • 2018-01-17
    • 2020-04-20
    • 2017-06-18
    • 1970-01-01
    • 2019-07-17
    • 1970-01-01
    相关资源
    最近更新 更多