NodeJS类方法异步返回

时间:2017-10-22 17:18:24

标签: javascript node.js

我目前正在使用登录方法在JavaScript中编写一个类。

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;

我正在使用请求模块发出HTTP请求,但请求正在使用异步调用,当从另一个文件调用undefined时,我总是收到console.log(client.login());。我已经看到许多针对具有回调的异步调用的解决方案,但我似乎无法通过类中的回调或承诺来解决这个问题。

2 个答案:

答案 0 :(得分:1)

有很多方法可以做到这一点 - 回调,事件,承诺。大多数人倾向于喜欢带有承诺的解决方案,这对他们来说是一个很好的用例。有了承诺,你可以这样做:

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

然后你可以打电话给它:

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

话虽如此,看起来你也将类定义为EventEmitter的子类,这表明你想要使用事件。您还可以使用它来指示登录,例如:

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

然后在致电login()

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

当然,您需要进行一些错误检查,并且您可能希望在登录后在您的实例上设置一个标志,因此您可以在初次登录后检查它。

答案 1 :(得分:0)

我认为login()应该返回一个承诺:

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

并在调用时:

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

我对NodeJS和异步编程都不熟悉,但我认为这是实现这一目标的方法。