2017-03-01 51 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