Node.js Promise代码在一个实例中工作,但在另一个实例中工作

时间:2017-10-13 08:24:15

标签: javascript mysql node.js promise es6-promise

我有一个node.js服务器端代码,它对mysql执行一些基本的数据库操作。我使用mysql2-promise作为库。

功能布局:

  • contacts_GET(contactid)=> getContactDetails();
  • contacts_GET(email)=> getContactId(email)=> getContactDetails(使用ContactID);

功能实现:

  contacts_GET : function(args, context, cb){
    if (args.pocid !== undefined ){
      db.getContactDetails(args.pocid)
        .then((results)=>{
          var resp = {
            "contacts" : results
          };
          cb(null, resp);
        }).catch((reason)=>{
          cb(JSON.stringify(errorHandler.throwInternalServerError(reason)));
        });
    }else if (args.email !== undefined ) {
      db.getContactId(null, args.email)
        .then((pocid)=>{
          logger.debug("got back pocid=", pocid);
          return db.getContactDetails(pocid);
        }).then((results)=>{
          logger.debug("got back result from getContactDetails=", results);
          var resp = {
            "contacts" : results
          };
          cb(null, responseObj(resp,args));
        }).catch((reason)=>{
          cb(JSON.stringify(errorHandler.throwInternalServerError(reason)));
        });
    }
  }


  getContactId : function(name, email, conn){
    logger.debug("Inside getContactId. [name, email]", name, email);
    if (conn === undefined ){
      return this.mysql.createConnection(this.options)
        .then((conn2)=>{
          const b = this.getContactId(name, email, conn2);
          conn2.end();
          return b;
        });
    }else{
      return conn.execute(`select pocid from Contacts where email = '${email}'`)
        .then(([rows, fields])=>{
          logger.debug("Inside getContactId. Result:", rows, fields);
          if (rows.length == 0) {
            return null;
          }else{
            return rows[0].pocid;            
          }
        });
    }
  }

  getContactDetails : function(pocid, conn){
    logger.debug("Inside getContactDetails. [pocid, defined conn]", pocid, (conn!==undefined));
    if (conn === undefined ){
      return this.mysql.createConnection(this.options)
        .then((conn2)=>{
          const b = this.getContactDetails(pocid, conn2);
          conn2.end();
          return b;
        });
    }else{
      const a = conn.execute("select name, email from Contacts where pocid=?", pocid)
        .then(([rows, fields])=>{
          logger.debug("Inside getContactDetails->cb. Result: ", rows);
          if (rows.length == 0) {
            return null;
          }else{
            return rows[0];            
          }
        });
      return a;
    }
  }

根据我的理解,在一个当时返回的Promise可以用来链接,我已经为这两个案例组成了承诺链。

  1. 传入contactid(pocid)时,只调用db.getContactDetails。在此函数中,它创建一个连接(返回一个promise),然后执行查询(这也返回一个promise),并解析和解析结果。此用例 有效

  2. 当传入电子邮件(email)时,处理程序(contacts_GET)创建一个promises链,从getContactId开始(返回一个链接连接创建,查询执行和结果解析的promise),链接到getContactDetails (与上述相同)。此用例失败

  3. 我的日志语句表明在第二种情况下,在getContactDetails函数中从conn.execute返回promise之后,执行突然停止。似乎Promise永远不会被执行,因此.then部分(查询的执行后)永远不会被调用。没有关于未处理拒绝的错误或警告。那时的控制就消失了。

    我很难理解为什么同一个函数在第一个用例中起作用但在第二个用例中失败。我已经阅读了Promise文档并阅读了每个关于边界场景的博客。我仍然对此感到茫然,并希望得到所有的帮助或指示。

    谢谢!

1 个答案:

答案 0 :(得分:0)

结束这个问题。我发现问题不在于我的Promise代码,而在于我如何处理Promise.catch中捕获的原因。这导致基础sql错误被忽略,导致我注意到的行为。

我还发现,node-mysql2包对待查询和执行方法的方式完全不同。使用查询方法,参数被正确转义和替换;而使用execute方法时,不执行参数替换。