【问题标题】:Running chronologically synchronous getJSON requests运行时间同步的 getJSON 请求
【发布时间】:2017-06-29 13:44:27
【问题描述】:

您好,我有两个针对天气项目的 JSON 请求,我需要来自第一个请求的数据,以便为用户个性化第二个请求。我的第一个请求获取用户的纬度和经度,第二个请求获取该位置当前天气的 url 中的坐标。

 var arrLocat = [];//users suburb, city, country, lat and lon
 var userURL = "";//specific url tailored off users lat and lon
 var userWeather = [];//current weather at users lat and lon

  $(document).ready(function(){
  //first JSON request
    $.getJSON("http://ip-api.com/json", function (data){
     arrLocat = data;
      userURL = "http://api.openweathermap.org/data/2.5/weather?lat=" + arrLocat.lat + "&lon=" + arrLocat.lon + "&appid=61c4ebe6f40d2e2d7085e7c42d287e1d&units=metric";
       console.log(arrLocat);THIS RETURNS FIRST, WORKS FINE
  })
  //second JSON request
    .then(function(){
     $.getJSON(userURL).done(function(index){
      userWeather = index;
       console.log(userWeather);//THIS RETURNS LAST, WORKS FINE BUT SHOULD RETURN SECOND
    });
  })
  //do stuff here
    .then(function(){
     $("#locat").text(arrLocat.city + ", " + arrLocat.regionName + ", " + arrLocat.country);
      console.log(userWeather);//THIS RETURNS BLANK GLOBAL VALUE, NOT CARRYING VALUE FROM SECOND .THEN FUNCTION ALSO SHOULD RETURN LAST NOT SECOND
  })
});

我正在尝试按照它们编写的顺序运行它们,我知道 getJSON 是异步的,但我认为 .then() 是为了强制顺序,等待前一个完成后再执行。

我花了很长时间才弄清楚发生了什么,似乎我的最后一个 .then() 在第二个 .then() JSON 请求之前运行。 我是延迟对象的新手,所以我可能正在做一些我不知道的根本错误?

【问题讨论】:

    标签: javascript jquery json ajax jquery-deferred


    【解决方案1】:

    首先,不要使用.done(),只使用.then().done() 是非标准的并且有一些奇怪的行为。 .then() 是标准的。

    其次,当你在 .then() 中有第二个 promise 时,你需要从 .then() 处理程序中返回它以正确链接它。

    在结构上,您希望它看起来像这样:

    $.getJSON(...).then(function(result1) {
        return $.getJSON(...)
    }).then(function(result2) {
       // do stuff here
    });
    

    并且,请注意,这里根本不需要全局变量,以便将最终结果放入最后一个 .then() 处理程序。您可能还会发现这很有用:

    How to chain and share prior results with Promises

    【讨论】:

    • 谢谢!我不知道我在做什么,但是你提供的结构帮助很大,我想我现在对 Promises 有了更多的了解。
    【解决方案2】:

    通过在彼此内部调用自己将它们链接在一起,无需使用 .then() ,它是承诺的一部分,并非所有 API 都以这种方式实现...

    var arrLocat = [];//users suburb, city, country, lat and lon
    var userURL = "";//specific url tailored off users lat and lon
    var userWeather = [];//current weather at users lat and lon
    
    $(document).ready(function(){
    //first JSON request
      $.getJSON("http://ip-api.com/json", function (data){
        arrLocat = data;
        userURL = "http://api.openweathermap.org/data/2.5/weather?lat=" + arrLocat.lat + "&lon=" + arrLocat.lon + "&appid=61c4ebe6f40d2e2d7085e7c42d287e1d&units=metric";
        console.log(arrLocat);
        $.getJSON(userURL).done(function(index){
          userWeather = index;
          console.log(userWeather);//THIS RETURNS LAST, WORKS FINE BUT SHOULD RETURN SECOND
          $("#locat").text(arrLocat.city + ", " + arrLocat.regionName + ", " + arrLocat.country);
          console.log(userWeather);//THIS RETURNS BLANK GLOBAL VALUE, NOT CARRYING VALUE FROM SECOND .THEN FUNCTION ALSO SHOULD RETURN LAST NOT SECOND
        });
      });
    });
    

    【讨论】:

    • Promise 是一种比普通回调更强大的异步操作管理方案,特别是在排序和传播错误或协调多个异步操作时。
    • 感谢您的帮助,代码绝对有效,但使用 Promises 进行操作对于新手来说是一种更好的学习体验
    猜你喜欢
    • 1970-01-01
    • 2012-05-11
    • 1970-01-01
    • 2013-06-01
    • 2019-05-13
    • 2014-07-30
    • 1970-01-01
    • 2019-09-13
    • 1970-01-01
    相关资源
    最近更新 更多