2016-12-05 97 views
1

所以我有一個承諾鏈,它解決了我遇到的某個回調地獄。在承諾鏈中混合變量

這裏的鏈條是什麼樣子:

server.exchange(oauth2orize.exchange.password(
    function(client, email, password, scope, done) { 
     users.findOne({email: email}) 
      .then(authenticateUser) // mix in password here? 
      .then(deleteExistingTokens) 
      .then(createAndSaveNewTokens) 
      .then(function(results){ 
       done(null, results[0], results[1], {'expires_in': tokenLife}); 
      }).catch(err => {done(err);}); 
    })); 

所以users.findOne返回返回我的用戶的承諾。我需要'混入'密碼以進行身份​​驗證。鑑於這是我對authenticateUser的定義,我將如何着手在鏈中插入新變量?

const authenticateUser = (err, user) => { // add password here? 
    return Promise((resolve, reject) => { 
     if (!user) { 
      reject('User not found'); 
     } 
     try { 
      return User(user).authenticate(password) 
      .then((result) => { 
       if (result) { 
        resolve(user); 
       } else { 
        reject('Invalid password'); 
       } 
      }); 
     } 
     catch (err) { 
      reject('Invalid user'); 
     } 
    }); 
}; 
+0

的'這一定義authenticateUser'不使用它'then'兼容,或者通過'password'進去。它需要更新。 –

+0

我做錯了什麼? –

+0

我將它添加到我的答案中。 –

回答

6

你這樣做,通過使用一個內聯函數:

.then(value => authenticateUser(value, password)) // mix in password here? 

你必須更新authenticateUser,不過,因爲在你的問題的簽名是舊式回調的NodeJS這不接受密碼,而不是傳遞給then的功能。

也許這樣的事情(看評論,也請繼續閱讀):

const authenticateUser = (user, password) => { 
    // We shouldn't need to create a new promise here, we have one 
    // from `authenticate` below we can use 
    return Promise((resolve, reject) => { 
     if (!user) {      // This shouldn't be 
      reject('User not found');  // necessary...? 
     }         // ... 
     try { 
      // No `return` on th enext line, doesn't do anything 
      // useful in the Ppromise init callback 
      User(user).authenticate(password) 
      .then((result) => { 
       if (result) { 
        resolve(user); 
       } else { 
        reject('Invalid password'); 
       } 
      }); 
     } 
     catch (err) { 
      reject('Invalid user'); 
     } 
    }); 
}; 

注意,在上面,我獨自邏輯在then回調上authenticate,但它不應該爲解決null爲用戶,所以你的then回調應該能夠假設用戶是有效的(這簡化了以上)。 authenticate應該如果認證失敗,則拒絕

另請注意,由於authenticate返回承諾,我們不應該在authenticateUser中創建一個新承諾。

這裏是我採取在一個完全新的authenticateUser

const authenticateUser = (user, password) => { 
    // This `try` is only here to guard against possible exceptions 
    // from `User` or `authenticate` 
    try { 
     return User(user).authenticate(password); 
    } 
    catch (Exception e) { 
     return Promise.reject(e); 
    } 
}; 
+0

我注意到你在那裏只有價值。功能簽名是否首先出錯? –

+0

@MathieuBertin:不,這是舊式的NodeJS回調。使用承諾時,成功和失敗採用不同的途徑。解決方法是成功的,它遵循'then'軌跡(傳遞給'then'的第一個函數)。拒絕是錯誤的,它遵循'catch'軌跡(或者傳遞給'then'的第二個函數)。 –