为什么$(document).ready()不能在API调用中?

时间:2017-04-02 21:30:48

标签: javascript json getjson

FYI试验1不起作用,但试验2有效。

我知道getJSON是异步执行的,但我实际上并不了解它是如何应用于我编写的代码的。

我可以从中学到什么异步执行?

为什么我必须将getJSON调用分离为与ready()分开的函数?

FOR TRIAL 2: 如何编写此代码,以便我不必初始化getJSON中的函数?如果没有办法,我怎么能写这段代码才能更健壮?

SORT_ALG(ARRAY, (sizeof(ARRAY)/sizeof(ARRAY[0])))

1 个答案:

答案 0 :(得分:2)

.ready() jQuery Documentation

  

指定在DOM完全加载时要执行的函数。

我可以从中学到什么异步执行?

您的学习知道您何时不知道文档ready()所以我们要等到事件完成后再开始执行我们的应用程序。您还了解到必须等待$.getJSON获取处理数据的json then

为什么我必须将getJSON调用分离为与ready()分开的函数?

如上所述,.ready()正在等待DOM完全加载,然后我们启动应用程序。所以,当我们准备好了#34;让我们获取天气数据。当DOM完全加载时,文档只能一次

如何编写此代码,以便我不必初始化getJSON中的函数?

如果没有具体说明,我假设你的问题是切换摄氏度和华氏度之间的度数。加载天气后,您可以将数据存储在函数范围之外的变量中,这样当您单击以更改可以传递相同数据的度数时,无需再次调用api(尽管此时天气可能已经改变了)

如何编写此代码以使其更强大?

我已经包含了改变你的代码的JS Bin。最大的问题是错误的命名约定而不是保持简单。示例getWeather()不是"得到天气"它是根据我们从您$.getJSON调用的ready()中获取的数据设置html,而不是将其分解为我们稍后可以调用的另一个函数。

在大多数情况下,这是代码现在读取的方式,清晰的函数名称有助于快速查看此代码应该执行的操作。

$(document).ready(function() {
  renderWeather(); 
});

var state = {
    fahrenheit: true,
    data: {}
};

function renderWeather() {
  getWeatherJSON()
    .then(data => {
      state.data = data; 
      setWeatherHTML(data);
      setTemperatureHTML(data, state.fahrenheit);
      setLocationHTML(data);
    })
    .catch(err => console.log(err));
}

http://jsbin.com/cekite/edit?js,output

如果我们想更进一步,我们可以创建一个隐藏我们的html渲染功能的WeatherAPI原型,并使用WeatherUndergroudAPI原型扩展它,这样如果我们改变我们的气象服务,我们只需要实现格式化功能以WeatherAPI预期的方式对数据进行编组。

class WeatherAPI {
  constructor(opt) {
    ...
  }

  init() {
    ...
  }

  get() {
    ... feteches json from endpoint provided
  }

  renderWeather() {
    this.get()
      .then(this.formatter.bind(this))
      .then(this.setWeatherData.bind(this))
      .then(this.renderWeatherHTML.bind(this))
      .then(this.renderTemperatureHTML.bind(this))
      .then(this.renderLocationHTML.bind(this))
      .catch(err => console.log(err));
  }

  formatter(data) {
    ...
  }

  setWeatherData(data) {
    ...
  }

  renderWeatherHTML() {
    ...
  }

  renderTemperatureHTML() {
    ...
  }

  renderLocationHTML() {
    ...
  }
}

扩展WeatherAPI就是传入新端点以获取数据。或者在这种情况下覆盖WeatherAPI get方法并返回静态数据。

class FakeWeatherAPI extends WeatherAPI {
  constructor(opt = {}) {
    super(opt);
  }

  get() {
    return new Promise((resolve) => {
      const data = {
        someReallyWeirdKeyForACity: 'San Francisco',
        state: 'CA',
        country: 'US',
        lat: '37.77999878',
        lon: '122.41999817',
        f: '1000',
        c: '25',
        icon: 'http://www.nyan.cat/cats/zombie.gif',
        weather: 'Acid Rain'
      };

      resolve(data);
    });
  }

  formatter(data) {
    const formattedData = {
      city: data.someReallyWeirdKeyForACity,
      state: data.state,
      country: data.country,
      lat: data.lat,
      lon: data.lon,
      temperature: {
        fahrenheit: data.f,
        celsius: data.c
      },
      icon: data.icon,
      weather: data.weather
    };

    return formattedData;
  }
}

然后我们的应用程序初始化代码变为。

$(document).ready(init);

function init(){
  const weatherAwesomeService = new FakeWeatherAPI();
  weatherAwesomeService.init();
};

以上是

以上的jsbin

http://jsbin.com/sicofe/edit?js,output