2017-10-22 1 views
1

Ich schreibe gerade eine Klasse in JavaScript mit einer Login-Methode.NodeJS-Klassenmethode Asynchrone Rückgabe

const EventEmitter = require('events'); 
const util = require('util'); 
const Settings = require('./config'); 
const config = new Settings(); 
const http = require('request'); 

class Client extends EventEmitter { 

constructor(username, password) { 
    super(); 
    this.username = username; 
    this.password = password; 
} 

get login() { 
    return this.login(); 
} 



login() { 
    http.post({ 
     url:  config.host + "v" + config.version + "/method/account.signIn.inc.php", 
     body: "username="+ this.username + "&password=" + this.password + "&clientid=" + config.clientid 
    }, function(error, response, body){ 
     return body; 
    }); 
    } 
} 

module.exports = Client; 

Ich bin mit dem Anforderungsmodul auf HTTP-Anfragen zu machen, aber Anfrage asynchrone Aufrufe verwendet, und ich bin immer undefined bekommen, wenn console.log(client.login()); aus einer anderen Datei aufrufen. Ich habe viele Lösungen gesehen, die auf asynchrone Aufrufe mit Rückrufen abzielen, aber ich kann es nicht mit Rückrufen oder Versprechen innerhalb einer Klasse herausfinden.

+1

Es macht keinen Unterschied, in einer 'Klasse' zu ​​sein. Verwenden Sie die gleichen Lösungen, die Sie gefunden haben. – llama

+0

Nun, das funktioniert nicht wirklich. Ich kann keinen Callback-Parameter im Getter definieren. Anmelden(); als Funktion funktioniert auch nicht. – JbSel

+0

Verwenden Sie dann keinen Getter. Oder verwenden Sie einen anderen Methodennamen als den Getter. In beiden Fällen können Sie das Ergebnis nicht direkt an den Aufrufer senden. – llama

Antwort

1

Es gibt viele Möglichkeiten, dies zu tun - Rückrufe, Ereignisse, Versprechen. Die meisten Menschen neigen dazu, die Lösungen mit Versprechen zu mögen, und dies ist ein guter Anwendungsfall für sie. Mit Versprechungen können Sie etwas tun:

login() { 
    return new Promise((resolve, reject) => { 
     http.post({ 
     url: config.host + "v" + config.version + "/method/account.signIn.inc.php", 
     body: "username="+ this.username + "&password=" + this.password + "&clientid=" + config.clientid 
     }, function(error, response, body){ 
      if (error) return reject(error) 
      resolve(body); 
     }); 
    }) 
} 

Dann können Sie es nennen:

let client = new Client(username, password) 
client.login() 
.then(result => { 
    // result available here 
}) 
.catch(err => { 
    // an error 
}) 

Having said that, es sieht auch wie Sie die Klasse als Unterklasse von EventEmitter, definieren was darauf hindeutet, Sie möchten Ereignisse verwenden. Sie können dies auch die Anmeldung mit so etwas wie angeben verwenden:

login() { 
    http.post({ 
    url:  config.host + "v" + config.version + "/method/account.signIn.inc.php", 
    body: "username="+ this.username + "&password=" + this.password + "&clientid=" + config.clientid 
    }, (error, response, body) => { 
    this.emit("loggedIn", body) 
    }); 
} 

warten dann für die Veranstaltung, nachdem Sie login()

let client = new Client(username, password) 
client.on("loggedin", (returnVal) => console.log("returned", returnVal)) 
client.login() 

Natürlich nennen, werden Sie einige Fehlerprüfung wollen, und Sie‘ Ich möchte wahrscheinlich nach der Anmeldung eine Markierung für Ihre Instanz setzen, so dass Sie dies nach der ersten Anmeldung überprüfen können.

+0

Das funktioniert perfekt, vielen Dank! Ja, ich benutze Emitter und dein Beispiel ist sehr hilfreich. Wie würde ich eine Variable hinzufügen? Die API gibt ein 'authToken' zurück, das an anderer Stelle mit der API interagieren muss. – JbSel

+0

@JbSel Sie können übergeben, was Sie wollen, in 'this.emit()' und dann erhalten Sie es im Handler - Ich aktualisierte die Antwort. Er gibt die 'body'-Variable aus und empfängt sie als' returnVal' –

+0

Dies ist nicht der Ansatz, den ich machen wollte, ich habe im Konstruktor die Variable 'this.accessToken = null;', sie ist null und nach dem emit-Ereignis in ' login(); 'Ich setze die Variable' this.accessToken = body.accessToken; 'Aber es ist immer noch null, wenn ich sie in der anderen Datei mit' console.log ("AccessToken:" + client.accessToken); '. – JbSel

0

Ich denke login() ein Versprechen zurückgeben sollte:

login() { 
    return new Promise((resolve, reject) => { 
    http.post({ 
     url: config.host + "v" + config.version + "/method/account.signIn.inc.php", 
     body: "username=" + this.username + "&password=" + this.password + "&clientid=" + config.clientid 
    }, function(error, response, body) { 
     if (error) reject(error); 
     else resolve(body); 
    }); 
    }); 
} 

und beim Aufruf:

client.login().then(result => console.log(result)); 

Ich bin irgendwie neu zu NodeJS und asynchrone Programmierung, aber ich denke, es ist die Art und Weise ist, dies zu tun .