2017-03-01 49 views
0

我想从承诺而不是所有这些嵌套函数中受益。下面的代码工作(以一种方式哈哈)。问题是,当它检测到用户名或电子邮件存在时,它返回"Email is already in use.""Username is already in use.",然后仍然执行最后一个承诺p3,它将用户添加到数据库(它不应该)。也许我误解了这个概念。什么是正确的方法来做到这一点?如何在承诺拒绝时停止执行?

var p1 = new Promise(
    (res, rej) => { 

     Database.doesEmailExist(userObj.email, 

      (err, exists) => { 

       if(err) return rej(err); 
       if(exists) return rej("Email is already in use."); 
       return res(); 
      } 

     ); 


    } 
); 

var p2 = new Promise(
    (res, rej) => { 

     Database.doesUsernameExist(userObj.username, 

      (err, exists) => { 

       if(err) return rej(err); 
       if(exists) return rej("Username is already in use."); 
       return res(); 

      } 

     ) 
    } 
); 

var p3 = new Promise(
    (res, rej) => { 

     Database.addUserToDB(userObj.username, userObj.email, bcrypt.hashSync(userObj.password), 

      (err) => { 

       if(err) return rej(err); 
       return res(); 

      } 

     ) 

    } 
); 

Promise.all([p1, p2, p3]).then(success => { 

    return callback("true", "You have successfully registered."); 

}).catch(reason => { 

    return callback("false", reason); 

}); 
+2

仍然执行什么其他的语句? 'Promise.all()'并行运行所有操作。如果你想让它们按顺序运行,你需要一个不同的方案。像往常一样,如果你描述你正在努力完成的事情,我们可以帮助你更好。 – jfriend00

+0

对不起,我解释得不好。将编辑。所以说数据库中存在一个用户名。它将运行'rej()'并返回给用户“用户名已被使用”,但它不会停止执行下一个Promise'p3'。即使先前的承诺被拒绝,它也会将用户添加到数据库中。 – user2287474

+1

因为你已经开始了所有三个异步操作。 'Promise.all()'只是监控所有三个,并告诉你他们什么时候完成或者他们中的任何一个被拒绝。如果你想排序你的操作,只有在上一步成功完成时才执行下一步,请描述你想要的问题。 – jfriend00

回答

1

您在同一时间运行的P1,P2和P3:承诺在运行,并且比Promise.all等待,直到所有的人都完成了。

您应该首先检查用户名和电子邮件是否有效,然后保存新用户。

var checkEmail =() => new Promise(
    (res, rej) => { 
     Database.doesEmailExist(userObj.email, 

      (err, exists) => { 

       if(err) return rej(err); 
       if(exists) return rej("Email is already in use."); 
       return res(); 
      } 

     ); 


    } 
); 

var checkUsername =() => new Promise(
    (res, rej) => { 

     Database.doesUsernameExist(userObj.username, 

      (err, exists) => { 

       if(err) return rej(err); 
       if(exists) return rej("Username is already in use."); 
       return res(); 

      } 

     ) 
    } 
); 

var saveUser =() => new Promise(
    (res, rej) => { 

     Database.addUserToDB(userObj.username, userObj.email, bcrypt.hashSync(userObj.password), 

      (err) => { 

       if(err) return rej(err); 
       return res(); 

      } 

     ) 

    } 
); 

Promise.all([ checkUsername(), checkEmail() ]).then(saveUser).then(() => { 

    return callback("true", "You have successfully registered."); 

}).catch(reason => { 

    return callback("false", reason); 

}); 

您的代码可以这样表示:(时间是在x轴上)

p1   --------> . 
p2   ---->  . 
p3   ------> . 
____________________________________________ 
         OK ? callback("true") 
         ERROR ? callback("false") 

而我更喜欢这样的:

checkEmail() --------> . 
checkUsername() ---->  . 
saveUser()    . ---------------> . 
________________________________________________ 
          OK ? continue  OK ? callback("true") 
          ERROR ?   ERROR ? callback("false") 
           \__________________/ 
+1

我回答太迟了,它看起来像你已经解决了你的问题 –

+0

谢谢你的彻底答案。对我来说很重要,它使得它非常干净整洁。 – user2287474