首页 > 解决方案 > return 不会终止一个 promise/then 链

问题描述

我有以下用于注册用户的代码。

const pgp = require('pg-promise')();
const crypto = require('./crypto.js');

const db = pgp(connection);

const querySelect = (text, params) => {  
  const s = pgp.as.format(text, params);  
  return db.any(s)
  .then(data => {    
    return data;    
  })
  .catch(error => {
    return error;
  });
}

const queryInsert = (text, params) => {  
  const s = pgp.as.format(text, params);  
  return db.one(s)
  .then(data => {    
    return data;    
  })
  .catch(error => {
    return error;
  });
}

const signup = (user) => {
  return new Promise((resolved, rejeted)=>{    
    return querySelect('select username from user WHERE username = $1', [user.username])      
    .then(res => {
      if (res.length == 0) {              
        return true;
      }      
      return resolved(false);  //SHOULD STOP + RETURN HERE                                 
    })
    .then(hashPasswordRes=>{      
      return crypto.hashPassword(user.password);
    })
    .then(queryRes=>{      
      if (queryRes) {
        return queryInsert('insert into user (username,password) values ($1,$2) RETURNING id', 
        [user.username, user.password]);      
      } else {            
        return rejeted('error while signup');
      }
    })
    .then(res=>{
      resolved(true);          
    })
    .catch(error => {
        return rejeted('error while signup');
    });// catch
  }) //promise
};//signup

exports.signup = signup;

这基本上是整个文件。我猜很简单。

问题是,在我评论的地方SHOULD STOP + RETURN HERE它确实返回false(这意味着已经是一个现有的用户名,就像插入的用户名一样)但是执行永远不会停止,所以用户最终保存在数据库中(即使return resolved(false);执行了)。

我在这里做错了什么?当我的代码中只有pg模块时,这曾经有效。当我使用pg-promise时,它​​开始出现这个问题。

坦率地说,我不知道为什么“返回”也不会停止函数执行。请指教

(节点 8.11.1, express 4.16.3, pg 7.4.2, pg-promise 8.4.4)

谢谢

编辑

作为记录,这是没有 pg-promise 的同一个文件,它工作得很好。变量名称发生了变化,但您可以看到逻辑。我尝试对 pg-promise 使用相同的逻辑

  const crypto = require('./crypto.js');
  const {Client} = require('pg');


const getuser = (mail, client) => {
  return new Promise((resolved, rejeted)=>{
    return client.query('select mail from user WHERE mail = $1',[mail])
    .then(res => {
      resolved(res.rows);
     })
     .catch(e => {
        rejeted(e);
        client.end();
     }); // catch
  })//promise
} //getUser


const signup = (user) => {
  return new Promise((resolved, rejeted)=>{
    client.connect().then(() => {
        getuser(user.email, client) 
        .then(getUserRes => {
          if (getUserRes.length==0) {
            return true;
          }
          client.end();
          return resolved(false);
        })
        .then(hashPasswordRes=>{
            return crypto.hashPassword(user.password);
        })
        .then(queryRes=>{
          if (queryRes) {
            const nowtime = new Date();
            return client.query('insert into user(mail, password) values ($1,$2)',
            [user.email, queryRes])
          } else {
            client.end();
            return rejeted('some error');
          }
        })
        .then(res=>{
          resolved(true);
          client.end();
        })
    }) // client.connect then
    .catch(error => {
      rejeted('some error');
      client.end();
    });// catch
  }) //promise
};//signup


exports.signup = signup;

标签: node.jsexpresspgpg-promise

解决方案


return 结束当前正在运行的函数,它不是 Promise 链。所以这部分:

return resolved(false);  //SHOULD STOP + RETURN HERE 

结束当前函数,即:

res => {
      if (res.length == 0) {              
        return true;
      }      
      return resolved(false);  //SHOULD STOP + RETURN HERE                                 
    }

注意箭头声明了一个函数。

如果你想停止链条,你可以做这样的事情

Promise.resolve(res)
.then(res => {
    if (shouldKeepGoing(res)) {
        return allTheOtherPromises(res)
    }
    return true
})

const allTheOtherPromises = res => {
    // Here you do all the promises you were doing
}

推荐阅读