【问题标题】:In NodeJS, how do I make database queries inside of a Promise?在 NodeJS 中,如何在 Promise 中进行数据库查询?
【发布时间】:2017-08-06 16:57:23
【问题描述】:

NodeJS 6.9.3

我之前的做法是这样的:

一个名为“get_user()”的外部函数:

return database_queries.get_user(user_name)
  .then(function(results_from_database) {

然后该函数使用 Knex 运行数据库调用,并返回:

            var dbquery = Multiline.stripIndent(function () {/*
                                                              SELECT
                                                              u.id as profile_id,
                                                              'user' as type_of_profile

                                                              FROM
                                                              user_profile u

                                                              WHERE name REGEXP "[[:<:]]||user_name||[[:>:]]"
                                                            */});

            dbquery = dbquery.replaceAll('||user_name||', user_name);

            return DB.knex.raw(dbquery).then(function(result1) {

                for(var index_of_results = 0; index_of_results < result1[0].length; index_of_results++) {

                    var document1 = result1[0][index_of_results];
                    array_of_maps_with_profile_type_and_profile_id[document1["type_of_profile"]].push(document1["profile_id"]); 

                }

当我这样做时,数据库查询运行并获取数据,但这是异步发生的,结果从未返回到外部函数。换句话说,外部函数在数据库查询运行之前很久就完成了。

所以我尝试将内部函数包装在 Promise 中:

function get_user(user_name) {

return new Promise(function(resolve, reject) {

    resolve ()
        .then(function() {

            var dbquery = Multiline.stripIndent(function () {/*
                                                              SELECT
                                                              u.id as profile_id,
                                                              'user' as type_of_profile

                                                              FROM
                                                              user_profile u

                                                              WHERE name REGEXP "[[:<:]]||user_name||[[:>:]]"
                                                            */});

            dbquery = dbquery.replaceAll('||user_name||', user_name);

            return DB.knex.raw(dbquery).then(function(result1) {

                for(var index_of_results = 0; index_of_results < result1[0].length; index_of_results++) {

                    var document1 = result1[0][index_of_results];
                    array_of_maps_with_profile_type_and_profile_id[document1["type_of_profile"]].push(document1["profile_id"]); 

                }

现在似乎从未调用过数据库调用。当它们运行时,它们会出现在日志中,但现在日志中不会出现任何数据库查询。看起来这个内部函数现在返回了一个 Promise,但从未调用过 Promise 的“resolve()”部分。

我在这里做错了什么?

【问题讨论】:

  • knex.raw 返回一个承诺,所以你不需要在这里创建Promise
  • 然后数据库查询在后台运行,而不是返回给调用数据库函数的函数。正在从循环中调用数据库函数。
  • 在node.js中没有background,这个函数是异步的。这意味着它不会立即返回结果。
  • @alexmac -- 是的,我知道。我不清楚你想说什么。
  • @alexmac -- 我希望在调用代码的 .then() 块中捕获结果。

标签: node.js promise knex.js


【解决方案1】:

这里有一个更简单的方法来编写基本相同的查询:

function get_user(user_name) {
  const regex = `[[:<:]]${user_name}[[:>:]]`;
  return DB.knex('user_profile')
    .where(DB.knex.raw(`?? REGEXP ?`, ['name', regex]))
    .then(res => {
      // do what ever you like with returned rows here
    });
}

【讨论】:

    【解决方案2】:

    您可能想稍微简化一下。

    看看这些示例项目。

    https://github.com/joicenunes/helloapp

    https://github.com/joicenunes/exercicio02

    https://github.com/joicenunes/exercicio03

    https://github.com/joicenunes/exercicio-04

    (还有更多,但你可以找到其余的)

    同时避免“replaceAll”并使用绑定变量。

    最后,由于您使用的是 node 6.x,您可以使用一些 es6 的好东西(箭头函数、多行字符串、类等),让语言为您工作。

    【讨论】:

    • 还有什么更简单的呢?一个函数调用另一个函数,该函数进行一些数据库调用并返回结果。如果您发现可以更简单的方法,请告诉我。
    猜你喜欢
    • 1970-01-01
    • 2018-02-01
    • 1970-01-01
    • 2017-02-08
    • 1970-01-01
    • 1970-01-01
    • 2018-05-15
    • 2013-11-22
    相关资源
    最近更新 更多