【问题标题】:external function call, promise, async and Mongo - confused外部函数调用、promise、async 和 Mongo - 困惑
【发布时间】:2018-11-22 16:09:45
【问题描述】:

这里开始感觉很厚。读了很多书,我相信我很好地理解了 promises 和 async-await。但是,我似乎很难在其他地方使用该函数,这样我才能获得结果(例如,我在另一个 js 文件中挂起:let dbConnection = dbOperations.openDatabaseConnection();)。

有人可以向我解释为什么我一直在等待以下函数(用 promise 和 asyncawait 编写的相同函数)吗?在函数内返回之前,我可以按预期控制台记录 dbConnection 结果。另外,我特别热衷于从这个意义上理解 Promise,因为似乎许多 npm 包似乎都返回了 Promise(根据我的经验,至少 async-await 不能很好地适应它?-> 使用 async 不会等待根据我的经验解决)。

//建立数据库连接

function openDatabaseConnection() {

    let dbConnection = {};

    return mongodb.connect(dbUri).then(conn => {
        dbConnection.connection = conn;
        return dbConnection;
    })
    .then(() => {
        dbConnection.session = dbConnection.connection.db(dbName);
        //console.log(dbConnection);
        return dbConnection;
    })
    .catch(err => {
        throw err;
    });
};

//建立数据库连接

async function openDatabaseConnection() {

    let dbConnection = {};

    try {
        dbConnection.connection = await mongodb.connect(dbUri);
        dbConnection.session = await dbConnection.connection.db(dbName);
    } finally {
        //console.log(dbConnection);
        return dbConnection;
    };
};

【问题讨论】:

  • “我一直处于待处理状态”是什么意思?
  • 如果你的then接受了返回的连接会更有意义,那么你就不需要let dbConnection,即.then((dbConnection) => {dbConnection.session...
  • 谢谢利亚姆,注意到您也为下面的答案做出了贡献,这很好地解释了这一点

标签: javascript mongodb promise async-await


【解决方案1】:

这两个函数都再次返回一个承诺。

所以在你的声明中let dbConnection = dbOperations.openDatabaseConnection(); 你分配一个承诺。

因此您需要执行以下操作:

dbOperations.openDatabaseConnection().then((dbConn) => ..)

let dbConnection = await dbOperations.openDatabaseConnection(); 

(请注意,这需要包装在 async 函数中)

【讨论】:

  • 谢谢!很清楚,现在看起来很明显。另一个问题与使用 Promise 和 async-await 之间的区别有关。上面的 await 看起来非常简洁,从某种意义上说,我可以以一种在整个文件中可见的方式声明一个变量。这是否可以通过承诺实现,或者是这样吗?上面要使用dbConn我要在箭头函数内操作吗?或者是否可以在该函数之外提取变量?想要投票,但还没有足够的代表这样做
  • 这实际上是 async/await 的用法 - 只是允许您以同步方式编写异步(承诺)代码的语法糖 - 与原生承诺相比,它没有任何其他优势。使用 async await 你的变量也只是在当前的 async 函数范围内可见,与.then((dbConn) => { .. }) 中的不同,对吧? :)
  • 啊,没有意识到 :) 仍然在承诺点上钻研,这样它就可以等效为异步使用:让 dbConnection = await...,它只是:让dbConnection = dbOperations.openDatabaseConnection().then((dbConn) => ..)?
  • 以这种方式尝试它似乎至少不起作用(尽管没有尝试很多变化,除了返回)->在该函数之外记录它时导致再次挂起(而使用异步我可以在函数之外记录它,例如在 let dbConnection = await... 下方)。承诺尝试过的之一: let dbConnection = dbOperations.openDatabaseConnection().then((dbConn) => { dbConnection = dbConn; }); console.log(dbConnection);
  • 有了promises,你只有在函数中可用的已完成数据——因此你传递它,所以在结算时,函数可以用数据调用。在 JS 中的迭代器/生成器的支持下(参考:developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/…),async/await 被简单地添加为语法糖。你已经检查过promisejs.org/generators 了吗?可以帮助您更好地理解 Promise 和生成器/迭代器 async/await 的工作原理
【解决方案2】:

Async/await 只是使用 Promise 的另一种方式,只是不要等待不是 Promise 的东西。

async function openDatabaseConnection() {

  let dbConnection = {};

  try {
    dbConnection.connection = await mongodb.connect(dbUri);
    // await here does not make sense, this function does not return a Promise
    // dbConnection.session = await dbConnection.connection.db(dbName);
    dbConnection.session = dbConnection.connection.db(dbName);
  } finally {
    //console.log(dbConnection);
    // return will always execute, keep here only when it should
    // return an empty object if the connection fails
    return dbConnection;
  };
};

More info on async/await

【讨论】:

  • 谢谢!很好的 cmets 可以帮助我理解这些似乎仍然不透明的部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-15
  • 2015-07-13
  • 2020-03-25
  • 2020-09-22
  • 2011-05-18
  • 2019-12-12
  • 1970-01-01
相关资源
最近更新 更多