无法在$ .post回调中设置范围变量

时间:2015-02-01 08:49:34

标签: javascript jquery asynchronous callback scope

我有以下类型的结构:

(function(){

var objects = [];

$('button.one').on('click', function(){

  fetchObjects = function(objects) {
    $.post("/fetchObjects")
      .done(function(data){
        objects = data;
        console.log(objects.length);
      });
  }
  fetchObjects(objects)

});

$('button.two').on('click', function(){
  console.log(objects.length);
});

})();

你可以看到我有一个变量objects,它是本函数的本地变量。最初是空的。当我单击button.one时,我希望使用来自某个ajax请求的返回值填充objects。它似乎有效,但是当点击button.two时,objects变量仍然是一个空数组。

为什么jQuery回调中没有objects可用?

我也尝试过这种方法但结果相同:

function callback(data) {
  facilities = data
}

$.post("/fetchObjects")
.done(function(data){
  callback(data);
});

我在这里缺少什么?请不要告诉我让“对象”全球化。

2 个答案:

答案 0 :(得分:1)

我不知道你为什么要传递对象作为参数。我认为以下应该可以正常工作。如果你想要取得其他成就,请告诉我。

(function(){

var objects = [];

$('button.one').on('click', function(){

  fetchObjects = function() {
    $.post("/fetchObjects")
      .done(function(data){
        objects = data;
        console.log(objects.length);
      });
  }
  fetchObjects()

});

$('button.two').on('click', function(){
  console.log(objects.length);
});

})();

答案 1 :(得分:0)

让我们简化一下代码。你基本上有这个:

var objects = [];

fetchObjects = function(innerObjects) {
  var data = ['a','b'];
  innerObjects = data;
  console.log(innerObjects.length);
};

fetchObjects(objects);
console.log(objects);

(为了清楚起见,我更改了另一个objects变量的名称;即使它具有相同的名称,问题也是一样的。)

当您调用该函数时,innerObjects包含对objects的引用,因此修改它也会更改原始数组。但是当你做的时候

innerObjects = data;

现在而不是修改数组,而是用其他东西替换引用。 innerObjects“指向”data而不是objects,原始变量保持不变。

要使其工作,您需要循环遍历data数组(假设它始终是一个数组)并将内容逐个分配给objects引用。这样您就可以保留原始引用并修改原始数组。

var objects = [];

fetchObjects = function(innerObjects) {
  var data = ['a','b'];
 
  for( var i = 0; i < data.length; i++ ) {
      innerObjects[i] = data[i];
  }
  console.log(innerObjects.length);
};

fetchObjects(objects);
console.log(objects);

或者,在您的实际代码中:

(function(){

var objects = [];

$('button.one').on('click', function(){

  fetchObjects = function(objects) {
    $.post("/fetchObjects")
      .done(function(data){
        for( var i = 0; i < data.length; i++ ) {
          objects[i] = data[i];
        }
        console.log(objects.length);
      });
  }
  fetchObjects(objects)

});

$('button.two').on('click', function(){
  console.log(objects.length);
});

})();