简体   繁体   English

理解异步/等待nodejs

[英]Trouble understanding async/await nodejs

Ok so I´m having troubles understanding how async/await, Promises, etc. in nodejs work, this is my first time programming in an asynchronous language. 好的,所以我很难理解nodejs中async / await,Promises等的工作方式,这是我第一次使用异步语言进行编程。

What im trying to do here is basically select one random entry from the mongoose-model "SecSolution". 我在这里要做的基本上是从猫鼬模型“ SecSolution”中随机选择一个条目。 Currently when arr is returned it´s empty, and the debug message on the bottom gets printed before the debug on the top gets printed. 当前,当返回arr时,它为空,并且在打印顶部的调试之前,先打印底部的调试消息。 I just want the function to return "arr" after it gets its value. 我只希望函数在获得其值后返回“ arr”。

async function getRandomCardIds(deckIdentifier, cardCount) {
    let arr;
    switch (deckIdentifier) {
        case 102:
            await SecSolution.count().exec(async function (err, count) {
                let promises = [];
                var random = Math.floor(Math.random() * count);
                for (let i = 0; i < 2; i++) {
                    promises.push((await SecSolution.findOne().skip(random).lean())._id);
                }
                arr = await Promise.all(promises);
                debug("This gets printed second" + arr);
            });
            break;
    }
    debug("this gets printed first");
    return arr;
}

Thanks in advance! 提前致谢!

Do not use callbacks when working with async / await . 使用async / await时不要使用回调。 (And when working with plain promises, use only then callbacks). (而用普通的诺言工作时, 只能使用then回调)。 Also you shouldn't use await on a promise that you still need as a promise object, to pass it to Promise.all . 同样,您不应该将await用作您仍然需要作为Promise.all对象的Promise.all ,以将其传递给Promise.all Your code should be 您的代码应为

async function getRandomCardIds(deckIdentifier, cardCount) {
    switch (deckIdentifier) {
        case 102:
            const count = await SecSolution.count(); // a promise(like object)
            let promises = [];
            var random = Math.floor(Math.random() * count);
            for (let i = 0; i < 2; i++) {
                promises.push(SecSolution.findOne().skip(random).lean());
            }
            let arr = await Promise.all(promises);
            debug("This gets printed second" + arr);
            return [arr[0]._id, arr[1]._id];
            break;
    }
    debug("this gets printed first");
    return undefined;
}

Instead of accessing the _id s on the objects in the result array, you could also have transformed the promises directly (similar to what you tried with the await ): 除了访问结果数组中对象的_id ,您还可以直接转换promise(类似于您对await尝试):

promises.push(SecSolution.findOne().skip(random).lean().then(card => card._id));

well basically you have to think that it will try to run everything and all the code that needs to wait to be resolved wont stop the process of running all the code. 好的,基本上,您必须考虑到它将尝试运行所有内容,并且所有需要等待解决的代码都不会停止运行所有代码的过程。

thus, looking at your code, we can see the following: 因此,查看您的代码,我们可以看到以下内容:

1) define arr as undefined then go inside the switch. 1)将arr定义为undefined然后进入开关内部。

2) in the switch statement we have an await so it will wait (but it wont stop the other code to run because it is not on the same statement), it will resolve later. 2)在switch语句中,我们有一个await因此它将等待(但它不会停止其他代码的运行,因为它不在同一条语句中),它将稍后解决。

3)prints the debug message 3)打印debug信息

4) returns undefined because the await inside of switch is not resolved. 4)返回undefined因为未解决switch内部的await。

5) one day the statement is resolved but nothing you can do about it. 5)有一天该陈述已解决,但您无能为力。

an example could be the following. 下面是一个示例。

 function resolveAfter2Seconds() { return new Promise(resolve => { setTimeout(() => { resolve('resolved'); }, 2000); }); } async function asyncCall() { console.log('calling'); var result = await resolveAfter2Seconds(); console.log(result); // expected output: "resolved" } asyncCall(); 

so what you can do in your case is the following: 因此,根据您的情况,您可以执行以下操作:

 function resolveInnerFunct() { return new Promise(resolve => { let promises = []; var random = Math.floor(Math.random() * count); for (let i = 0; i < 2; i++) { promises.push(SecSolution.findOne().skip(random).lean())._id)); } Promise.all(promises).then(values=> {return resolve(values)}; }); } async function asyncCall() { console.log('calling'); let arr; switch (deckIdentifier) { case 102: // this will wait until the resolveInnerFunct resolves. arr = await resolveInnerFunct(); debug("this wont get printed before the other message") break; } debug("this gets printed first"); return arr; } asyncCall(); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM