1

多年来一直使用这个网站,但之前从未发布过问题 :-) 来了..

我有一个 javascript 对象,我想在初始化时根据谷歌 API 为其分配一个值。没关系,但谷歌响应不包含对调用它的对象的引用,所以我需要找到一种方法将 ID 传递到链中。

我希望下面的例子有意义,基本上我想要的 API 响应不会包含对启动它的对象的引用——所以我需要一种将它关联回调用它的对象的方法。

注意:这是伪代码

    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;  :-(
4

3 回答 3

2

在 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.
});
于 2013-08-14T12:43:25.153 回答
0

您可以使用 apply、call 或 bind 更改函数 (this) 的范围(bind 将返回另一个范围已更改的函数)。

所以在你的情况下

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

或者你可以在回调中使用 self 。

编辑在初始化代码中,您需要等到获取值:

var entity = new myClass(foo);
(function delay() {
    if (!entity.distanceFromSomething) {
        return setTimeout(delay, 100);
    }
    alert(entity.distanceFromSomething);
});
于 2013-08-14T12:35:14.463 回答
0

谢谢大家,我使用了您的解决方案的组合,这些解决方案很有效!

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

}

于 2013-08-14T13:57:50.573 回答