我正在尝试在nodejs中创建一个模块,所以我创建了一个名为Client的Object,它有自己的构造函数和一些方法。
问题是构造函数运行异步请求(使用请求),并且方法需要正确调用构造中的东西。
如何让构造函数同步?
function Client(id){
var token;
o = {
method: 'POST',
url: url + '/getToken',
headers: headers,
json: true,
body: id }
request(o).then(function(body) {
token = JSON.parse(body).token
})
function getValue(){
return new Promise(function(ff, rj) {
o = {
method: 'GET',
url: url + '?token=' + token,
headers: headers
}
request(o).then(function(body) {
ff(JSON.parse(body).value)
})
})
}
return{
getValue
}
}
我想做这样的事情
var client = Client(id)
client.getValue().then(console.log)
但是,由于请求的异步,当getValue返回错误时(令牌还没有值) 我怎么能这样做?谢谢
答案 0 :(得分:2)
您应该将token
作为依赖项并单独执行异步,可能在某种工厂函数中。
function Client(token) {
this.getValue = function () {
return request({
method: 'GET',
url: url + '?token=' + token,
headers: headers
}).then(function (body) {
// Notice that you can return a synchronous value instead of a
// promise here. It will be wrapped in a promise and the next
// .then call will receive this returned value.
return JSON.parse(body).value;
});
}
}
function clientFactory (id) {
return request({
method: 'POST',
url: url + '/getToken',
headers: headers,
json: true,
body: id
}).then(function (body) {
var token = JSON.parse(body).token;
return new Client(token);
});
}
或者如果你想使用es6类和&箭头功能:
class Client {
constructor (token) {
this.token = token;
}
getValue () {
return request({
method: 'GET',
url: `${url}?token=${this.token}`,
headers: headers
}).then((body) => JSON.parse(body).value);
}
}
function clientFactory (id) {
return request({
method: 'POST',
url: `${url}/getToken`,
headers: headers,
json: true,
body: id
}).then((body) => new Client(JSON.parse(body).token));
}
es6类示例实际上更好,因为您没有为getValue
的每个新实例重新创建Client
方法。要使第一个示例与es6示例一样高效,您必须这样做:
function Client(token) {
this.token = token;
}
Client.prototype.getValue = function () {
return request({
method: 'GET',
url: url + '?token=' + this.token,
headers: headers
}).then(function (body) {
return JSON.parse(body).value;
});
};
现在你应该能够做到这样的事情:
var client = clientFactory(id).then(function (client) {
client.getValue().then(console.log);
});