【问题标题】:Database Querying function not running asynchronously数据库查询功能未异步运行
【发布时间】:2020-06-07 02:58:04
【问题描述】:

所以我在我的节点服务器中创建了一个函数,它接收一个查询字符串,在我的数据库上运行它,然后返回结果。然后,我想在整个路由中使用 async await 来异步使用我的函数,而不是在其中嵌套查询、嵌套查询、嵌套查询等。

代码如下:

 const runQuery = queryString => {
    console.log("...runQuery")
    db.query(queryString, (error, results, fields) => {
        if (error) {
            console.log("runQuery: FAILURE");
            return error;
        }
        else {
            console.log("runQuery: SUCCESS");
            return(results);
        }
    })
}

register.post("/", async (req, res) => {
    console.log(req.body);
    const results = await runQuery("select * from test1");
    res.send(results);
})

数据库应该有 3 个条目,但不幸的是,它什么也没返回。意思是 results 在发送时是一个空变量,这意味着 JS 永远不会正确地等待它来捕获 db 结果。我怎样才能异步使用我的函数,这怎么可能?

【问题讨论】:

  • 你的db对象是什么?
  • 它是我从另一个文件导入的基本 mysql 连接对象。
  • 我知道它是一个连接对象。当人们问起时,我们通常的意思是把代码也放上去,或者像 mysql 一样从包 some-pacakge 中描述它。您正在尝试使用 Promise 但并非所有软件包都提供承诺支持
  • 啊,我明白了。对此表示歉意。但是是的,我今天再次检查了问题,发现 mysql 包没有承诺支持。我的数据库连接来自常规的 mysql 包。

标签: javascript mysql node.js express asynchronous


【解决方案1】:

您的函数“runQuery”似乎没有返回承诺,实际上,它没有返回任何内容。您在 db.query 函数的回调中使用“return”,而不是函数“runQuery”本身。

由于 runQuery 正在执行一个异步操作,结果应该通过一个 Promise 来解决(这是您的请求处理程序中的“等待”正在寻找的内容)。

我不太确定,但您似乎正在使用 MySql,我在 mysql 包的 npm 页面上找不到任何关于被承诺的查询的信息,所以我们将自己承诺:

const runQuery = (queryString) => new Promise((resolve,reject) => {
    console.log("...runQuery")
    db.query(queryString, (error, results, fields) => {
        if (error) {
            console.error("runQuery: FAILURE");
            reject(error);
        } else {
            console.log("runQuery: SUCCESS");
            resolve(results);
        }
    })

})

register.post("/", async (req, res) => {
    console.log(req.body);
    try{
        const results = await runQuery("select * from test1");
        res.send(results);
    }catch(e){
        console.error(`ERROR THROWN BY runQuery:`,e);
        res.status(500).send({
            message: e.message || "INTERNAL SERVER ERROR"
        })
    }
})

请注意,如果发生错误,我们的 promisified 函数将拒绝该错误,并且不会将其存储在我们的请求处理程序的“结果”变量中。相反,将引发需要处理的错误。因此,将任何 async/await 调用放在 try/catch 中始终是一个好习惯。

【讨论】:

  • 非常感谢 Anuj,您的回答很有效,并教会了我一些关于承诺的知识!我很抱歉没有提到我使用的是基本的 mysql 包。事实证明,正如另一位用户提到的,并非所有包都支持承诺。我假设所有 db-management 包都自动应用了 promise 包装器。我是一名实习生,所以这对我来说是全新的,但你的回答帮助我展示了一种使用 Promise JS 类的新动态方式。非常感谢。不幸的是,我的代表太低而无法投票,否则你会得到一个。对不起:(
  • 不客气!没关系,我们都是来学习的。继续编码!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-17
  • 1970-01-01
  • 2018-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-05
相关资源
最近更新 更多