在NodeJS中,如何在Promise中进行数据库查询?

时间:2017-08-06 16:57:23

标签: node.js promise knex.js

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,但是&#34; resolve()&#34;承诺的一部分永远不会被召唤。

我在这里做错了什么?

2 个答案:

答案 0 :(得分:2)

这是一种更简单的方法来编写基本相同的查询:

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
    });
}

答案 1 :(得分:1)

您可能希望简化一下。

看看这些示例项目。

https://github.com/joicenunes/helloapp

https://github.com/joicenunes/exercicio02

https://github.com/joicenunes/exercicio03

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

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

还要避免使用“replaceAll”并使用绑定变量。

最后,由于你使用的是节点6.x,你可以使用一些es6好东西(箭头函数,多行字符串,类等),让语言适合你。