2016-12-05 1 views
1

So habe ich eine Versprechen-Kette, die eine bestimmte Rückruf-Hölle löst, die ich erlebte.Mischen von Variablen in einer Versprechenskette

Hier ist, was die Kette wie folgt aussieht:

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);}); 
    })); 

So users.findOne ein Versprechen gibt, die meine Benutzer zurückgibt. Ich muss das Passwort "einmischen", um sich zu authentifizieren. Da dies meine Definition von authenticateUser ist, wie würde ich neue Variablen in die Kette einfügen?

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

Diese Definition von 'authenticateUser' nicht kompatibel ist mit dem es mit' then', oder mit dem Übertragen von 'password' hinein. Es muss aktualisiert werden. –

+0

Was mache ich falsch? –

+0

Ich habe es meiner Antwort hinzugefügt. –

Antwort

6

Sie tun das, eine Inline-Funktion unter Verwendung:

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

Sie werden authenticateUser aktualisieren müssen, obwohl, da die Signatur in Ihrer Frage ist ein im alten Stil NodeJS Rückruf, die nicht der Fall ist Akzeptieren Sie ein Passwort, keine Funktion, die an then übergeben werden soll.

Vielleicht so etwas wie dieses (Kommentare sehen, sondern auch lesen Sie weiter):

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'); 
     } 
    }); 
}; 

Beachten Sie, dass in den oben genannten, ich die Logik in der Callback-then auf authenticate allein gelassen habe, aber es sollte nicht be mit null für den Benutzer auflösen, so sollte Ihr then Rückruf in der Lage sein, davon auszugehen, dass der Benutzer gültig ist (was das obige vereinfacht). authenticate sollte ablehnen, wenn die Authentifizierung fehlschlägt.

Beachten Sie auch, dass, da authenticate eine Zusage zurückgibt, wir keine neue in authenticateUser erstellen müssen.

Hier ist mein nehmen auf einem völlig neuen 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

Mir ist aufgefallen, dass du dort nur Wert hast. Setzt die Funktionssignatur den Fehler nicht zuerst? –

+0

@MathieuBertin: Nein. Das sind alte NodeJS Callbacks. Bei der Verwendung von Versprechen verlaufen Erfolg und Misserfolg auf unterschiedlichen Wegen. Die Auflösung ist erfolgreich und folgt dem 'then'-Trail (die erste Funktion wurde an' then' übergeben). Die Zurückweisung ist ein Fehler und folgt dem 'catch'-Trail (oder der zweiten Funktion, die an' then' übergeben wird). –

Verwandte Themen