Node.js 为什么由异步函数组成的函数没有返回正确的值?(NodeJS)

Node.js 为什么由异步函数组成的函数没有返回正确的值?(NodeJS),node.js,async-await,Node.js,Async Await,在异步函数中分配的变量未返回预期输出 我目前正在编写一个NodeJS函数,该函数从MongoDB数据库中查找对象(数据库工作正常),并在找到对象时返回对象。问题在于,包含异步函数的函数不会等到前面的函数完成。我对JS和NodeJS比较陌生,所以我可能误解了异步函数的作用 async function findUserByEmail (userEmail) { var mg = require('mongodb').MongoClient; var user; awai

在异步函数中分配的变量未返回预期输出

我目前正在编写一个NodeJS函数,该函数从MongoDB数据库中查找对象(数据库工作正常),并在找到对象时返回对象。问题在于,包含异步函数的函数不会等到前面的函数完成。我对JS和NodeJS比较陌生,所以我可能误解了异步函数的作用

async function findUserByEmail (userEmail) {
    var mg = require('mongodb').MongoClient;

    var user;

    await mg.connect(url, { useNewUrlParser: true, useUnifiedTopology: true }, async function(err, db){
        var dbo = db.db(myDB);
        var query = { email : userEmail };

        await dbo.collection("Users").findOne(query).then((result)=>{
            user = result;
            db.close();
        });
    });

    return user;
}

我试图在“findOne(query)”函数中返回分配给“user”的值,但是,返回的值始终是“未定义的”。

您混合了回调和异步调用。让我把它清理干净。瞧,这里有一些应该有用的东西(你有一些我不知道的值,比如myDB和url)


注意:我建议在应用程序启动时打开MongoDB连接一次,在因任何原因关闭时重新打开,并在应用程序停止时关闭,因为为每个请求打开新连接会增加一些显著的开销(可能慢25倍).

您可以使用
var user=await mg.connect..
获取它,并使用
return wait dbo.collection..
return result
db.close()之后。但我很好奇为什么它不是这样工作的。您当前的节点版本是什么?您可以尝试其他版本,可能在某些版本中已修复。我正在使用版本6.9.0。我还尝试了您的第一条评论,它似乎仍然给出了相同的问题,您可以尝试升级到node
8.16.0
,例如使用包
n
。(
npm install-g n&&n 8.16.0
)我会试试的,谢谢。可能需要一个
try/catch
,这样如果前面的
wait
语句被拒绝,你就可以关闭数据库。@jfriend00我同意,但总的来说,我不建议在与抓取函数相同的函数中打开和关闭数据库连接。它有一些相当大的开销。现在你正在“吃”错误,如果查询拒绝,就不让调用者看到被拒绝的承诺。好的,你现在明白了。顺便说一句,我同意不为一个查询打开和关闭数据库连接的观点。仅供参考,您不需要捕获
,除非您想在那里记录错误。只要
try/finally
就可以了。
async function findUserByEmail (userEmail) {
    var mg = require('mongodb').MongoClient;
    var db = await mg.connect(url, { useNewUrlParser: true, useUnifiedTopology: true });
    var result;

    // Add a Try/Catch to capture any errors, 
    // such that the database can still be closed
    try {  
        var dbo = db.db(myDB);
        var query = { email : userEmail };
        result = await dbo.collection("Users").findOne(query);
    } catch (error) {
        throw error;   
    } finally {
        db.close();
    }
    return result;
}