SQL Query的结果未传递给Node Js Promise中的resolve()

时间:2017-03-02 04:27:08

标签: javascript mysql node.js

所以我认为我做得对,但我猜不是。我试图将查询结果传递给then()中的函数。我在两个函数中有一个console.log()日志记录结果。第一个应该吐出结果。第二个是给我undefined,我无法弄清楚我做错了什么。

    var dbConnect = () => new Promise(
        (res, rej) => {

            var connection = mysql.createPool(Config.mariaDBCred);

            connection.getConnection((err, connection) => {

                if(err) return rej(err);
                return res(connection);

            });


        }
    );

    var dbQuery = (connection, queryString, paramArray) => new Promise(
        (res, rej) => {

            var sql = mysql.format(queryString, paramArray);

            connection.query(sql,
                (err, results, fields) => {

                    connection.release();

                    console.log(results); //THIS DISPLAYS RESULTS FROM THE QUERY CORRECTLY
                    if(err) return rej(err);
                    return res(results, fields);

                }
            );

        }
    );


    //CHECK IF EMAIL EXISTS
    module.exports.doesEmailExist = (email, callback) => {

        dbConnect().then(
            (connection) => {
                dbQuery(
                    connection,
                    'SELECT `id`, `password_hash` FROM `users` WHERE email = ?',
                    [email]
                )
            }
        ).then(
            (results, fields) => {
                console.log(results); //THIS DISPLAY UNDEFINED
                if(results.length > 0) return callback(true, results);
                return callback(false, "Email does not exist.");
            }
        ).catch(
            (reason) => {
                console.log(reason);
                return callback(false, "Internal Error");
            }
        );

    }

1 个答案:

答案 0 :(得分:1)

我不确定以下编辑是否可以解决您的所有问题,但就Promise API方面的问题而言,它们应该引导您朝着正确的方向前进。

首先,在dbQuery函数中,我解析了一个对象,因为你只能解析一个promise中的单个值。

第二,要实现承诺,你必须回报承诺。在您的第一个then处理程序中,您没有从PromisedbQuery之后)返回dbConnect

最后,我更改了第二个then处理程序以使用单个已解析对象,而不是之前使用的多个参数。之前,如果一切正常,results将被定义,而不是fields。在这种情况下解决ArrayObject是一种很好的做法。如果你使用es6,对象/数组解构会使这一点变得容易。

另一个说明。如果您正在使用Promises,请考虑放弃在doesEmailExist函数中实现的回调模式,如果不是完全的话。它更加一致,除非针对特定的错误情况,否则您不必包装catch处理程序。值得深思。

var dbConnect = () => new Promise(
     (res, rej) => {

         var connection = mysql.createPool(Config.mariaDBCred);

         connection.getConnection((err, connection) => {

             if(err) return rej(err);
             return res(connection);

         });


     }
 );

 var dbQuery = (connection, queryString, paramArray) => new Promise(
     (res, rej) => {

         var sql = mysql.format(queryString, paramArray);

         connection.query(sql,
             (err, results, fields) => {

                 connection.release();

                 console.log(results); //THIS DISPLAYS RESULTS FROM THE QUERY CORRECTLY
                 if(err) return rej(err);
                 // return res(results, fields); NOPE, can only resolve one argu
                 return res({ results: results, fields: fields }) // resolve an object

             }
         );

     }
 );


 //CHECK IF EMAIL EXISTS
 module.exports.doesEmailExist = (email, callback) => {

     dbConnect().then(
         (connection) => {
            // Return the promise from `dbQuery` call
             return dbQuery(
                 connection,
                 'SELECT `id`, `password_hash` FROM `users` WHERE email = ?',
                 [email]
             )
         }
     ).then(
         (response) => {
            // Can only resolve one argument
            var results = response.results;
            var fields = response.fields;
             console.log(results); //THIS DISPLAY UNDEFINED
             if(results.length > 0) return callback(true, results);
             return callback(false, "Email does not exist.");
         }
     ).catch(
         (reason) => {
             console.log(reason);
             return callback(false, "Internal Error");
         }
     );

 }