等待仅在异步功能中有效

2020/11/18 13:22 · javascript ·  · 0评论

我写了这段代码 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;

我有一个错误

“等待仅在异步功能中有效”

有什么问题

错误不是指myfunction而是start

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

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

是否有与“返回等待”有关的性能问题?

当我收到此错误时,事实证明我在“异步”函数中调用了map函数,因此此错误消息实际上是指未标记为“异步”的map函数。通过从map函数中取消“ await”调用,并提出了一些其他获得预期行为的方法,我解决了这个问题。

var myfunction = async function(x,y) {
    ....
    someArray.map(someVariable => { // <- This was the function giving the error
        return await someFunction(someVariable);
    });
}

要使用await它,它的执行上下文必须是async自然的

如前所述,您需要先确定自己executing context愿意从事await的工作的性质

只需放在将要执行任务asyncfn声明之前async

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

说明:

在你的问题,你导入的是method这是asynchronous在本质上,将并行执行。但是,您尝试执行该async方法的地方是execution context您需要定义async使用的另一个地方await

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

想知道到底发生了什么

await使用承诺/未来/返回任务的方法/功能并将方法/功能async标记为能够使用等待。

另外,如果您熟悉promisesawait实际上会执行相同的Promise / Resolve过程。创建承诺链并在resolve回调中执行下一个任务

有关更多信息,请参阅MDN DOCS

async/的当前实现await仅支持函数await内部关键字async更改start函数签名,以便可以await在内部使用start

 var start = async function(a, b) {

 }

对于那些感兴趣的人,有关顶层的建议await目前处于阶段2:https : //github.com/tc39/proposal-top-level-await

我遇到了同样的问题,以下代码块给出了相同的错误消息:

repositories.forEach( repo => {
        const commits = await getCommits(repo);
        displayCommit(commits);
});

问题是方法getCommits()是异步的,但我正在将它传递给Promise也产生的参数repo。因此,我必须像这样向其添加async一词:async(repo)并开始工作:

repositories.forEach( async(repo) => {
        const commits = await getCommits(repo);
        displayCommit(commits);
});

异步/等待是处理诺言的机制,我们可以通过两种方式来实现

functionWhichReturnsPromise()
            .then(result => {
                console.log(result);
            })
            .cathc(err => {
                console.log(result);

            });

或者我们可以使用await等待诺言首先完全兑现,这意味着它被拒绝或解决。

现在,如果我们要在函数内部使用await(等待实现承诺),则必须强制容器函数必须是异步函数,因为我们正在等待异步实现承诺的||。有道理吧?

async function getRecipesAw(){
            const IDs = await getIds; // returns promise
            const recipe = await getRecipe(IDs[2]); // returns promise
            return recipe; // returning a promise
        }

        getRecipesAw().then(result=>{
            console.log(result);
        }).catch(error=>{
            console.log(error);
        });

如果您正在编写Chrome扩展程序,而您的代码的根源却出现此错误,则可以使用以下“替代方法”对其进行修复:

async function run() {
    // Your async code here
    const beers = await fetch("https://api.punkapi.com/v2/beers");
}

run();

基本上,您必须将异步代码包装在中async function,然后在不等待的情况下调用该函数。

“等待仅在异步功能中有效”

但为什么?“ await”明确地将异步调用转换为同步调用,因此,调用方不能是异步的(或异步的)-至少不是因为该调用是在“ await”进行的。

是的,await / async是一个很棒的概念,但是实现已完全中断。

无论出于何种原因,已经实现了await关键字,使其只能在async方法中使用。实际上,这是一个错误,尽管您在此处看不到它所指的错误。解决此错误的方法是实现await关键字,以便无论调用函数本身是同步还是异步的,它都只能用于调用异步函数。

由于该错误,如果在代码中的某个位置使用await调用真正的异步函数,则必须将所有函数标记为异步,并且所有函数调用都必须使用await。

从本质上讲,这意味着您必须将promise的开销添加到整个应用程序中的所有函数中,其中大多数不是,并且永远不会是异步的。

如果您真的考虑过,在函数中使用await应该要求包含await关键字的函数不要同步-这是因为await关键字将暂停在找到await关键字的函数中的处理。如果该函数中的处理被暂停,那么它肯定不是异步的。

因此,对于javascript和ECMAScript的开发人员-请按以下步骤修复await / async实现...

  • await只能用于CALL异步功能。
  • 等待可以以任何一种功能出现,同步或异步。
  • 将错误消息从“等待仅在异步函数中有效”更改为“等待只能用于调用异步函数”。
本文地址:http://javascript.askforanswer.com/dengdaijinzaiyibugongnengzhongyouxiao.html
文章标签: ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!