2016-10-16 289 views
0

我正在建设一个带有NodeJS后端的网上商店。 我有承诺,从数据库中选择USER_ID的令牌,然后我做的另一个选择从特定用户获取购物车数据:JavaScript承诺错误返回

function selectItemsFromCart(userToken){ 
    return new Promise(function(resolve, reject){ 
    var queryString = "SELECT id FROM users WHERE token='"+userToken.token+"'"; 
    return dbconn.query(queryString, function(err, res){ 
     if(err){ 
     reject(err); 
     } 
     var userId = res[0].id; 
     resolve(userId); 
    }); 
    }).then(function(userId){ 
    var queryString = "SELECT * FROM cart LEFT JOIN users ON cart.user_id='"+userId+"'"; 
    return dbconn.query(queryString, function(err,res){ 
     if(err){ 
     return err; 
     } 
     return res; 
    }); 
    }); 
} 

当我试图把它送回来给前是这样的:

app.use('/showCartItems', function(req, res){ 
    selectItemsFromCart(req.body).then(function(result){ 
    console.log(result); 
    res.send(result); 
    }).catch(function(err){ 
    res.status(500).end("Can't load cart"); 
    }); 
}); 

我的控制台,而不是显示我一起的结果,它显示了这个查询日志:

Query { 
    domain: null, 
    _events: 
    { error: [Function], 
    packet: [Function], 
    end: [Function], 
    timeout: [Function], 
    'start-tls': [Function] }, 
    _eventsCount: 5, 
    _maxListeners: undefined, 
    _callback: [Function], 
    _callSite: 
    Error 
     at Protocol._enqueue (/var/www/html/Web Shop Yoon/src/node_modules/mysql/lib/protocol/Protocol.js:141:48) 
     at Connection.query (/var/www/html/Web Shop Yoon/src/node_modules/mysql/lib/Connection.js:214:25) 
     at /var/www/html/Web Shop Yoon/src/script.js:155:19 
     at process._tickCallback (internal/process/next_tick.js:103:7), 
    _ended: false, 
    _timeout: undefined, 
    _idleNext: null, 
    _idlePrev: null, 
    _idleStart: null, 
    _idleTimeout: -1, 
    _repeat: null, 
    sql: 'SELECT * FROM cart LEFT JOIN users ON cart.user_id=\'15\'', 
    values: undefined, 
    typeCast: true, 
    nestTables: false, 
    _resultSet: null, 
    _results: [], 
    _fields: [], 
    _index: 0, 
    _loadError: null, 
    _connection: 
    Connection { 
    domain: null, 
    _events: {}.... 

我怎样才能得到我的承诺的权利返还?

+1

你正确使用'你的第一个'query'回调reject' /'resolve',但在你的第二个'query'回调中,你使用'return'来代替。为什么?你期望这些返回值用于什么? 'query'肯定不会(并且不能)返回它们。 –

+1

dbconn.query是异步的,不会返回一个Promise,因此你不能像这样使用它......你似乎已经为第一个dbconn.query做了正确的事情,你只是“忘记”包装第二个一个在Promise中 - 我建议为dbconn.query创建一个包装函数来Promisify它 –

+0

备注:您在客户端上使用Angular的事实与您的问题完全无关,并且可能让读者感到困惑(请参阅[这个答案尝试](​​http://stackoverflow.com/a/40069350/157247),例如,错误客户端代码的引用代码)。由于这是纯粹的服务器端,因此我会建议完全关闭Angular的事情(并相应地编辑了这个问题)。 –

回答

3

你只是没有完全承诺,代码。您首次使用query的承诺没有问题(除return之外没有任何作用),但是您没有完全将其应用到第二个承诺中。

除此之外:

  1. 至少有一个表面上的SQL注入风险,以及相当可能有两个,在代码;虽然你可能从上下文知道没有风险,但仍然通常值得使用API​​的功能来防御它。

  2. 当您在第一query,你在做reject(err);取回一个错误(这是正确的)使用res[0].id,这很可能被抛出异常,如果resundefinednull但随后继续到代码(它可能是)。虽然这是相对无害(例外将被转换为拒绝,将被忽略,因为以前的拒绝已经到位),这绝对是不正确的。 :-)你想在那里有一个else

看评论:

function selectItemsFromCart(userToken) { 
    return new Promise(function(resolve, reject) { 
     var queryString = "SELECT id FROM users WHERE token='" + userToken.token + "'"; 
     // WARNING!! SQL INJECTION RISK!! ------------------^^^^^^^^^^^^^^^^^^^^^^^^^ 
     dbconn.query(queryString, function(err, res) { // Note: No return on this line, it's not used for anything 
      if (err) { 
       reject(err); 
      } else {     // Note else 
       var userId = res[0].id; 
       resolve(userId); 
      } 
     }); 
    }).then(function(userId) { 
     // Note use of a new promise 
     return new Promise(function(resolve, reject) { 
      var queryString = "SELECT * FROM cart LEFT JOIN users ON cart.user_id='" + userId + "'"; 
      // WARNING!! Potential SQL INJECTION RISK!! --------------------------^^^^^^^^^^^^^^^^ 
      dbconn.query(queryString, function(err, res) { 
       if (err) { 
        reject(err); 
       } else { 
        resolve(res); 
       } 
      }); 
     }); 
    }); 
} 

或者,也有图书馆有使用的NodeJS样式的回调与err, response说法对,采取的API并将它们转换成承诺,指明分数的API来代替,处理这种管道为你。


重新SQL注入的警告,请参阅http://bobby-tables.com这不朽的漫画:

enter image description here

+1

另外我会改变'if(err){reject(err);如果(错误)返回拒绝(错误);'调用拒绝不退出函数。 – Keith

+0

@Keith:我刚刚看到了这一点,并将其标记出来(尽管使用了不同的解决方案)。接得好。 –

+0

我刚刚重读了代码:p –