web-dev-qa-db-fra.com

attendre n'est valable que dans la fonction async - eval dans async

Je veux évaluer () certaines lignes de code à l'intérieur de la fonction ASYNC. Alors que le code suivant est correct,

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

le suivant jette une erreur: attendre n'est valable que dans la fonction ASYNC

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

Comment pourrais-je gérer cela? Mon foo () devrait être async car il s'agit de la fonction de contrôleur de chippeter

8
Randy Vogel

Si vous voulez pouvoir attendre l'EVAL, vous pouvez utiliser ceci:

await Object.getPrototypeOf(async function() {}).constructor("your code here")();

Cela utilise le constructeur AsyncFunction. MDN a ne page sur elle qui décrit les différences entre l'utilisation et l'utilisation de eval:

Remarque: les fonctions asynchronisées créées avec le constructeur d'asyncconces ne créent pas de fermeture à leurs contextes de création; Ils sont toujours créés dans la portée mondiale.

Lors de leur exécution, ils ne pourront qu'elles ne pourront accéder à leurs propres variables locales et globales, et non celles de la portée dans laquelle le constructeur d'asyncisation a été appelé.

Ceci est différent de l'utilisation d'EVAL avec code pour une expression de fonction Async.

Cela signifie que si vous avez des variables que vous souhaitez que votre code évalué puisse accéder, vous devez les ajouter à globalThis:

const testVar = "Hello world";
globalThis["testVar"] = testVar;
const result = await Object.getPrototypeOf(async function() {}).constructor(`
    console.log(testVar);
    await myAsyncFunc();
    return testVar;
`)();
// result will be "Hello world"
delete globalThis["testVar"];
3
Merlin04

Si vous souhaitez appeler de manière dynamique du code ASYNC dans une fonction plus grande, vous pouvez fournir un rappel qui le fait pour vous. De cette façon, vous pouvez appeler votre fonction avec différentes fonctionnalités supplémentaires en lui donnant différentes fonctions de rappel pour exécuter:

// some sample async functions
var resolveAfter2Seconds = function() {
  console.log("starting slow promise -> ");
  return new Promise(resolve => {
    setTimeout(function() {
      resolve("slow");
      console.log("<- slow promise is done");
    }, 2000);
  });
};

var resolveAfter1Second = function() {
  console.log("starting fast promise ->");
  return new Promise(resolve => {
    setTimeout(function() {
      resolve("fast");
      console.log("<- fast promise is done");
    }, 1000);
  });
};

//a function that accepts a callback and would await its execution
async function foo(callback) {
  console.log("-- some code --");
  await callback();
  console.log("-- some more code --");
}

//calling with an async function that combines any code you want to execute
foo(async () => { 
  await resolveAfter2Seconds();
  await resolveAfter1Second();
})
1
VLAZ