return does not terminate a promise/then chain

时间:2018-06-04 17:48:28

标签: node.js express pg pg-promise

I have the following code that I use to signup users.

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;

This is basically the whole file. Pretty simple I guess.

The problem is that in the point where I comment SHOULD STOP + RETURN HERE it does return false (so that means that the is already an existing username like the one inserted) but the execution never stops, so the user ends up saved in the database (even though the return resolved(false); is executed).

What am I doing wrong here? This used to work when I had just the pg module in my code. When I used pg-promise, it started having this issue.

Frankly, I dont have a clue why the "return" doesnt also stop the function execution. Please advice

(node 8.11.1, express 4.16.3, pg 7.4.2, pg-promise 8.4.4)

Thanks

EDIT

for the record, here is the same file without pg-promise , that works just fine. The vars names change, but you can see the logic. I tried to use the same logic with 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;

1 个答案:

答案 0 :(得分:1)

返回结束正在运行的当前函数,这不是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
}