2017-03-02 64 views
1

所以我认为我是这样做的,但我猜不是。我试图将查询结果传递给then()中的函数。我在这两个函数中有一个console.log()日志结果。第一个应该是吐出结果。第二个是给我undefined,我无法弄清楚我做错了什么。来自SQL查询的结果没有传递给Node Js Promise中的resolve()

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

    } 
+0

等等......我需要把第二个'then()'放在第一个'then()'里面吗?但是,如果是这样的话,那我该如何避免使用两个渔获物? – user2287474

+0

nope,但这意味着你的第一个'then'工作不正常,请尝试从你的查询中删除反引号(选择用户名,密码...)' – Taki

+0

@Taki不幸的是,这没有奏效。 – user2287474

回答

1

我不知道,如果下面编辑将解决你所有的问题,但你的问题与问候到Promise API来说,他们应该引导你在正确的方向。

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

二,要链承诺,你必须返回承诺。在您的第一个then处理程序中,您没有从dbQuerydbConnect之后)返回Promise

最后,我将您的第二个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"); 
     } 
    ); 

} 
+0

对于这种见解,我无法感谢你。我真的很想把握承诺的概念。我想摆脱'callback()'并将所有内容都转换为Promises。只是一次只做一步。现在就试试这个。 – user2287474

+1

不客气!一旦你掌握了它,你就不会再回头看看事件,如果可以的话!特别是考虑es7 – Nindaff

+0

的'async/await'功能那么这个问题绝对可以解决。非常感谢。现在我只需要弄清楚为什么调用'doesEmailExist()'的函数即使在用户存在的情况下也能继续执行。大声笑。 – user2287474