[英]How to pass additional parameters to an encapsulated callback function in node.js
Have used this site for years but never posted a question before :-) Here goes.. 多年来一直使用这个网站,但之前从未发过一个问题:-)
I have a javascript object, which I would like to assign itself a value based on a google API when it's initialised. 我有一个javascript对象,我想在初始化时根据谷歌API为自己分配一个值。 That's all fine, but the google response doesn't contain the reference to which object called it, so I need to find a way to pass the ID down the chain. 这一切都很好,但谷歌响应不包含对哪个对象称为它的引用,所以我需要找到一种方法将ID传递给链。
I hope the below example makes sense, basically the API response I want will not contain a reference to the object that started it - so I need a way of associating it back to the object that called it. 我希望下面的例子有意义,基本上我想要的API响应不会包含对启动它的对象的引用 - 所以我需要一种方法将它关联回调用它的对象。
NOTE : THIS IS PSUDO CODE 注意:这是PSUDO代码
function myClass(param) {
this.property = param;
this.distanceFromSomething = 0;
this.init = function() {
// this will set this.distanceFromSomething
var url = 'http:// GOOGLE MAPS API URL BUILT HERE';
http.get(url, function(res) {
var body = '';
res.on('data', function(chunk) {body += chunk;});
res.on('end', function() {
var response = JSON.parse(body)
var distance = response.distance;
this.distanceFromSomething = distance;
// 'this' is no longer defined since it's asynchronous... :-(
// alternative...
setDistance(ID, distance);
// and I cannot get the ID of the current object from here either, since it's encapsulated :-(
// How can this callback function understand which object it relates to?
});
};
};
this.init();
}
var entity = new myClass(foo);
var undefined = entity.distanceFromSomething; :-(
In jcubic's answer, you won't get the desired result since distanceFromSomething
won't be set until http.get
is completed, so you need some sort of a callback. 在jcubic的回答,你不会得到想要的结果,因为distanceFromSomething
直到将不会设置http.get
完成,所以你需要某种回调。
function myClass(param) {
var self = this;
this.property = param;
this.distanceFromSomething = 0;
this.init = function(cb) {
// this will set this.distanceFromSomething
var url = 'http:// GOOGLE MAPS API URL BUILT HERE';
http.get(url, function(res) {
var body = '';
res.on('data', function(chunk) {body += chunk;});
res.on('end', function() {
var response = JSON.parse(body)
var distance = response.distance;
self.distanceFromSomething = distance;
setDistance(ID, distance);
if(cb) {
cb.bind(self)(); // "this" inside the callback will be bound to myClass instance.
}
});
};
};
}
var cls = new myClass({});
cls.init(function() {
console.log(this.distanceFromSomething); //init is done.
});
You can change the scope of the function (this) using apply, call or bind (bind will return another function with scope changed). 您可以使用apply,call或bind更改函数的范围(this)(bind将返回另一个更改范围的函数)。
so in your case just do 所以在你的情况下就这样做
function myClass(param) {
var self = this;
this.property = param;
this.distanceFromSomething = 0;
this.init = function() {
// this will set this.distanceFromSomething
var url = 'http:// GOOGLE MAPS API URL BUILT HERE';
http.get(url, function(res) {
var body = '';
res.on('data', function(chunk) {body += chunk;});
res.on('end', function() {
var response = JSON.parse(body)
var distance = response.distance;
this.distanceFromSomething = distance;
// 'this' will be from myClass scope
// alternative...
setDistance(ID, distance);
// and I cannot get the ID of the current object from here either, since it's encapsulated :-(
// How can this callback function understand which object it relates to?
}.bind(self)); // <--- HERE bind to self
};
};
this.init();
}
or you can just use self inside a callback. 或者你可以在回调中使用self。
EDIT And in initialized code you will need to wait until the value is fetched: 编辑在初始化代码中,您需要等到获取值:
var entity = new myClass(foo);
(function delay() {
if (!entity.distanceFromSomething) {
return setTimeout(delay, 100);
}
alert(entity.distanceFromSomething);
});
Thanks guys, I used a combination of your solutions which worked! 谢谢大家,我使用了你的解决方案的组合工作!
function myClass(param) {
this.property = param;
this.distanceFromSomething = 0;
this.init = function() {
// this will set this.distanceFromSomething
var url = 'http:// GOOGLE MAPS API URL BUILT HERE';
var self = this; // 'this' is still defined at this point
http.get(url, function(res) {
var body = '';
res.on('data', function(chunk) {body += chunk;});
res.on('end', function() {
var response = JSON.parse(body)
var distance = response.distance;
self.distanceFromSomething = distance;
setDistance(self.id, distance); // <-- this function receives self.id :-)
});
}.bind(self));
};
} }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.