await 仅在异步函数中有效

2022-08-30 00:07:19

我写了这个代码:lib/helper.js

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

然后我尝试在另一个文件中使用它:

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

我收到一个错误:

await is only valid in async function

问题出在哪里?


答案 1

错误不是指 ,而是指 。myfunctionstart

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();


我利用这个问题的机会来建议你一个已知的反模式,使用是: 。awaitreturn await


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');
})();

正确

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');
})();

另外,要知道有一个特殊情况,其中正确且重要:(使用try/catch)return await

“等待返回”是否存在性能问题?


答案 2

要使用 await,其执行上下文在本质上必须是异步

正如它所说,你需要在任何事情之前定义你愿意在哪里完成任务的性质。executing contextawait

只需将 async 放在将在其中执行异步任务的 fn 声明之前。

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')
}

解释:

在您的问题中,您正在导入一个本质上是并将并行执行的。但是,当您尝试执行该方法时,您需要定义该方法才能使用。methodasynchronousasyncexecution contextasyncawait

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

想知道引擎盖下发生了什么

await使用 promise/future/task-return 方法/函数,并将方法/函数标记为能够使用 await。async

另外,如果您熟悉,实际上正在执行相同的承诺/解决过程。创建承诺链并在回调中执行下一个任务。promisesawaitresolve

有关更多信息,您可以参考MDN DOCS