将变量从一个ajax调用传递给另一个

时间:2016-06-17 14:45:20

标签: javascript jquery ajax

我有这个codepen Localweather App我创建了两个函数。

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
$(document).ready(function() {

  var city = "Newcastle";
  
  city = getLocation();
  //set city to location from function; 
  console.log ("city undefined?" +city);
  //this is undefind, why?
  
  getWeather(city).then(function(data) {
    console.log(data);
    var weatherType = data.weather[0].description;
    var weatherId = data.weather[0].id;
    var tempF = Math.round(data.main.temp);
    var tempC = Math.round((tempF - 32) / 1.8);
    var wind = data.wind.speed;
    var name = data.name;
    console.log(weatherType);
    $('#weather').html(weatherType);
    $('#temp').html(tempC + "&#176;C");
    $('#wind').html(tempF + "&#176;F");
    $('#icon').html(weatherId);
    $('#location').html(name);
  
  })
});

function getLocation() {
  $.getJSON('http://ipinfo.io', function(data) {
    console.log("data" + data);
    city = data.city;
    console.log("city" + city);
    return city;
  })
}

function getWeather(place) {
  return $.getJSON('http://api.openweathermap.org/data/2.5/weather?q=' + place + '&units=imperial&APPID=90d625c068e3f3d7818b9e4237871e21');
}
 </script>

getWeather函数,它接收一个位置并返回该位置的天气对象。我也有一个getLocation函数,我想基于ip返回我的城市(是的,我知道它不准确,但它是我想要使用的)。

如果我对城市进行硬编码,那就有效。 但是尝试使用getLoction函数中的city变量是不行的。 我猜这是与异步有关但我通过在getLoction函数中使用回调它会返回'city',然后'然后'传递给getWeather。 或者我的想法都错了?

5 个答案:

答案 0 :(得分:1)

您需要使用(嵌套)回调,因为您需要等待来自AJAX调用的异步响应。

您的浏览器不会等待异步函数完成并继续运行到下一个语句,这就是代码中未定义city的原因 - 因为在代码中getLocation仅返回{{1}时的值完成。

如果你的函数会像这样,你会得到一个返回值,而不是你想要的那个(所以不要使用下面的代码片段,它只是为了解释)。

getJSON

在下面的示例中,我们将函数作为参数传递给function getLocation() { $.getJSON('http://ipinfo.io', function(data) { return data.city; // this will be ignored, because the browser will jump to the next statement }); return "XXX"; // <- this will be returned, because the browser will not wait for async functions to finish } 。参数名称为getLocation,我们在callback完成后使用data参数调用此函数。

我们可以从此数据参数中提取$.getJSON('http://ipinfo.io',然后调用city

请注意getWeather不再返回任何值,而是将getLocation参数传递给回调(或者您可以在data中提取city然后传递{{ 1}}代替回调。)

getLocation
city

答案 1 :(得分:1)

return city;中的

getLocation()仅从传递到function(data)的匿名函数$.getJSON返回。您的getLocation实际上没有return声明city = undefined

处理此问题的一种方法可能是使用getJSON承诺:

getLocation().then(function (data) {
    console.log(data);
    getWeather(data.city).then(...
});

然后getLocation看起来像:

function getLocation () {
    return $.getJSON(...
}

从答案中可以看出,有很多方法可以使用nested callbacksPromises来解决此问题。

Here you can see my codepen in action

答案 2 :(得分:1)

如果要链接AJAX调用,则需要在前一个回调中设置下一个AJAX调用。这样,下一个AJAX调用将仅在前一个AJAX调用完成后发送。

这个答案是一个细微的变化,使用IP地址来获取纬度/经度(而不是城市)&amp;然后将其用于天气。

http://codepen.io/anon/pen/ZOpEBQ

&#13;
&#13;
var ip = '8.8.8.8';

$.get('https://ipapi.co/'+ip+'/latlong/', function(data){
  
  data = data.split(',');
  console.log(data);
  
  $.get('http://api.openweathermap.org/data/2.5/weather?lat='+data[0]+'&lon='+data[1]+'&units=imperial&APPID=90d625c068e3f3d7818b9e4237871e21', function(data1) {
    
    // Should print the weather
    console.log(data1);  
  
  });
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
&#13;
&#13;
&#13;

答案 3 :(得分:0)

城市仍未定义,因为getWeather不会等待getLocation执行并为城市分配值。你总是可以把

$.getJSON('http://ipinfo.io', function(data) {
console.log("data" + data);
city = data.city;
console.log("city" + city);

$.getJSON('http://api.openweathermap.org/data/2.5/weather?q=' + city + '&units=imperial&APPID=90d625c068e3f3d7818b9e4237871e21');
})

或者您可以使用jQuery.Deferred()对象仅在完成城市时执行获取天气。

答案 4 :(得分:0)

基本上你需要在调用openwheater之前等待ipinfo回调,否则city将是未定义的,这是一个异步调用机制

$(document).ready(function() {

  getLocation().then(function(city){
      getWeather(city.city).then(function(data) {
        console.log(data);
        var weatherType = data.weather[0].description;
        var weatherId = data.weather[0].id;
        var tempF = Math.round(data.main.temp);
        var tempC = Math.round((tempF - 32) / 1.8);
        var wind = data.wind.speed;
        var name = data.name;
        console.log(weatherType);
        $('#weather').html(weatherType);
        $('#temp').html(tempC + "&#176;C");
        $('#wind').html(tempF + "&#176;F");
        $('#icon').html(weatherId);
        $('#location').html(name);

      }, function(err){
        console.log("ERROR!", err);
      })
  }, function(err){
     console.log("ERROR!", err);
  });
});

function getLocation() {
  return $.getJSON('http://ipinfo.io');
}

function getWeather(place) {
  return $.getJSON('http://api.openweathermap.org/data/2.5/weather?q=' + place + '&units=imperial&APPID=90d625c068e3f3d7818b9e4237871e21');
}