使通过函数加载的JSON可用于其他函数



我正在尝试用JS函数加载JSON,然后使加载的JSON对象可用于同一命名空间中的其他函数。我尝试过使用return来提供检索到的对象数组,但这不起作用。在所附的示例中,我已经将对象数组分配给了命名空间对象中的一个属性,但当我试图在主loadData函数之外获取该对象数组时,我得到的都是null。

这是我的JS:

var myObj = {
	jsonEndPoint: '/test/test.json',
	dataObjects: null
}
myObj.loadData = function () {
    $.ajax({
        url: 'test.json',
        type: 'POST',
        dataType: 'json',
        success: function (data) {
            myObj.dataObjects = data.apiResults[0].league.season.draft.rounds[0].picks;
            //console.log(myObj.dataObjects);
			
        },
        error: function (xhr, textStatus, errorThrown) {
            console.log('Data Load Error: ' + textStatus);
        }
    });
}()
myObj.displayData = function() {
	console.log(myObj.dataObjects)
}()

完整的示例如下所示:http://zbl.me/test/index.html我正在加载的JSON文件如下:http://zbl.me/test/test.json

这是因为JavaScript本质上是异步的——当您试图访问myObj.displayData函数中的myObj.dataObjects时,该对象还不存在,因为AJAX调用尚未完成。

您可以做的是,通过使用$.when(),确保所有需要AJAX调用中新添加数据的函数只有在AJAX调用传递了.done()承诺时才能运行。逻辑很简单:

  1. myObj.loadData()现在只用于进行AJAX调用。关于我们如何处理完成和失败事件(以前是.success().error()回调),我们将该逻辑委托给下一个函数
  2. myObj.displayData()现在用于评估使用myObj.loadData()进行的AJAX调用所返回的promise。您使用$.when()来获取promise,然后简单地连锁.done()来处理成功的调用,连锁.fail()来处理相反的调用:)

这是您改进的代码:

var myObj = {
    jsonEndPoint: '/test/test.json',
    dataObjects: null
}
myObj.loadData = function () {
    // We return the AJAX object so that we can evaluate the state later
    // This is very simple :) 
    return $.ajax({
        url: 'test.json',
        type: 'POST',
        dataType: 'json'
    });
}()
myObj.displayData = function() {
    // Instead of using the deprecated .success() and .error()
    // ... we use .done() and .fail()
    $.when(myObj.loadData).done(function(data) {
        myObj.dataObjects = data.apiResults[0].league.season.draft.rounds[0].picks;
    }).fail(function(xhr, textStatus, errorThrown) {
        console.log('Data Load Error: ' + textStatus);
    });
}()

如果您不确定,可以在此处检查伪代码:http://jsfiddle.net/teddyrised/5rbd2eqq/1/我使用了JSfiddle内置的JSON响应来生成人工响应,但逻辑与您的完全相同。

即使在ajax完成之前,也会调用displayData方法。因此,您要么需要在ajax的成功回调中调用displayData,要么稍微更改结构,使其易于调用。

你为什么不做一些类似的事情呢

var myObj = {
  jsonEndPoint: '/test/test.json',
  dataObjects: null,
  displayData: function() {
    console.log(this.dataObjects);
  },
  loadData: function() {
    $.ajax({
      context: this,
      url: 'test.json',
      type: 'GET',
      dataType: 'json',
      success: function(data) {
        this.dataObjects = data.apiResults[0].league.season.draft.rounds[0].picks;
        console.log(myObj.dataObjects);
        this.displayData();
      },
      error: function(xhr, textStatus, errorThrown) {
        console.log('Data Load Error: ' + textStatus);
      }
    });
  }
};
myObj.loadData();

这是一个演示

最新更新