2016-06-17 2 views
0

У меня есть этот код Localweather App Я создал две функции.Передача переменной из одного вызова ajax другому

<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 не работает. Я предполагаю, что это как-то связано с асинхронностью, но я, хотя, используя обратный вызов в функции getLoction, вернет «город», который «будет» передан в getWeather. Или я понял, что все неправильно?

+0

Что вы получите в консоли. журнальные звонки? –

+0

Вам необходимо работать с (вложенными) обратными вызовами. –

+0

Вам нужно связать вызовы методов, а затем успешно получить getLocation call getWeather с полученными данными. Посмотрите, как работают обратные вызовы ajax: http://api.jquery.com/jquery.getjson/ –

ответ

1

Вам необходимо работать с (вложенными) обратными вызовами, потому что вам нужно ждать асинхронных ответов от вызовов AJAX.

Ваш браузер не будет ждать, пока функции асинхронных, чтобы закончить и продолжать работать в следующем заявлении, поэтому город не определен в коде - потому что в вашем коде getLocation только возвращает значение, когда 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 в getLocation, а затем передать city на обратный вызов, а).

$(document).ready(function() { 
 

 
    getLocation(function(data) { 
 
     var city = data.city; 
 
     getWeather(city).then(function(data) { 
 
     // ... 
 
     }); 
 
    }); 
 
    }); 
 

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

 
    function getWeather(place) { 
 
    return $.getJSON('http://api.openweathermap.org/data/2.5/weather?q=' + place + '&units=imperial&APPID=90d625c068e3f3d7818b9e4237871e21'); 
 
    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"> 
 
</script>

+0

Спасибо, но вы можете объяснить мне поток. Возможно, это не технически правильно, но мы передаем большую часть программы в функцию определения местоположения. – Greyhounddad

+0

Поток объясняет сам. Сначала вам нужен город/место, прежде чем вы сможете позвонить getWeather. Как я уже сказал, ваш браузер не будет ждать завершения звонков AJAX, поэтому вам нужно связать вызовы и работать с обратными вызовами. Да, getLocation станет отправной точкой вашей программы, поэтому обязательно передайте код на функции (которые принимают параметры обратного вызова), иначе будет сложно прочитать и понять, что делает код. Пожалуйста, отметьте ответ как принятый, если он ответит на ваш вопрос. –

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() объект выполнять только получить погоду, когда получить город делается.

1

return city; в getLocation() возвращает только из анонимной функции function(data), который был принят в $.getJSON.Ваш getLocation фактически не имеет return заявления, которое делает city = undefined

Один из подходов к обработке это может быть, чтобы использовать getJSON Promise:

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

Тогда getLocation будет выглядеть:

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

Как вы можете видеть из ответов, есть много способов сделать это, используя nested callbacks или Promises.

Here you can see my codepen in action

0

В основном вам нужно ждать ipinfo обратного вызова до openwheater вызова, в противном случае город будет неопределенным, это механика асинхронной вызов

$(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'); 
} 
1

Если вы хотите приковать AJAX звонки, вы необходимо установить следующий вызов AJAX внутри обратного вызова предыдущего. Таким образом, следующий вызов AJAX будет отправлен только после завершения предыдущего.

Это ответ небольшой вариант, который использует IP-адрес для выбора широты/долготы (вместо города) &, а затем использует это для погоды.

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

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); 
 
    
 
    }); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Смежные вопросы