Здравствуйте. Я только недавно познакомился с асинхронным программированием в js и у меня возникли некоторые вопросы, ответы на которых пока не смог сам найти, по этому надеюсь на вашу помощь.
Задача: вывести список валютных пар, который содержит: название валюты, цену и изменение за 24 часа.
Демо страникаИнформация приходит в виде нескольких json файлов так как базовая валюта может быть только одна.
- USD/CAD, USD/CHF, USD/JPY, USD/RUB
- EUR/JPY, EUR/RUB, EUR/USD
- AUD/USD
- GBP/USD
- NZD/USD
Отдельный пункт списка это отдельный запрос json файла. Плюс все эти запросы можно умножить на 2, так как я запрашиваю еще вчерашние результаты, для калькуляции дельты (3 пункта выводимого списка). Всего получается 10 запросов.
У меня все получилось сделать. Результат заносится в DOM, только тогда, когда все запросы выполнились, но мне не нравится сам код, так как эти отдельные запросы я записываю отдельно. Хотелось бы пустить цикл.
Использовал я конструкцию $.when().then. Какой код сейчас:
var currency = [];
var last = [];
$.when(
$.ajax({
type: 'GET',
url: json.currency.USD.current,
dataType: 'json',
success: function(data) {
if (!data) return false;
for (var prop in data.rates) {
var options = {
name: 'USD/' + prop,
price: data.rates[prop]
};
currency.push(options);
}
}
}),
$.ajax({
type: 'GET',
url: json.currency.USD.last,
dataType: 'json',
success: function(data) {
if (!data) return false;
for (var prop in data.rates) {
var options = {
change: data.rates[prop]
};
last.push(options);
}
}
}),
$.ajax({
type: 'GET',
url: json.currency.EUR.current,
dataType: 'json',
success: function(data) {
if (!data) return false;
for (var prop in data.rates) {
var options = {
name: 'EUR/' + prop,
price: data.rates[prop]
};
currency.push(options);
}
}
}),
$.ajax({
type: 'GET',
url: json.currency.EUR.last,
dataType: 'json',
success: function(data) {
if (!data) return false;
for (var prop in data.rates) {
var options = {
change: data.rates[prop]
};
last.push(options);
}
}
}),
$.ajax({
type: 'GET',
url: json.currency.AUD.current,
dataType: 'json',
success: function(data) {
if (!data) return false;
for (var prop in data.rates) {
var options = {
name: 'AUD/' + prop,
price: data.rates[prop]
};
currency.push(options);
}
}
}),
$.ajax({
type: 'GET',
url: json.currency.AUD.last,
dataType: 'json',
success: function(data) {
if (!data) return false;
for (var prop in data.rates) {
var options = {
change: data.rates[prop]
};
last.push(options);
}
}
}),
$.ajax({
type: 'GET',
url: json.currency.GBP.current,
dataType: 'json',
success: function(data) {
if (!data) return false;
for (var prop in data.rates) {
var options = {
name: 'GBP/' + prop,
price: data.rates[prop]
};
currency.push(options);
}
}
}),
$.ajax({
type: 'GET',
url: json.currency.GBP.last,
dataType: 'json',
success: function(data) {
if (!data) return false;
for (var prop in data.rates) {
var options = {
change: data.rates[prop]
};
last.push(options);
}
}
}),
$.ajax({
type: 'GET',
url: json.currency.NZD.current,
dataType: 'json',
success: function(data) {
if (!data) return false;
for (var prop in data.rates) {
var options = {
name: 'NZD/' + prop,
price: data.rates[prop]
};
currency.push(options);
}
}
}),
$.ajax({
type: 'GET',
url: json.currency.NZD.last,
dataType: 'json',
success: function(data) {
if (!data) return false;
for (var prop in data.rates) {
var options = {
change: data.rates[prop]
};
last.push(options);
}
}
})
).then(function() {
setResult($('.list.currency').createHead(), $.extend(true, currency, last));
});
Чтобы все работало приходится описывать каждый запрос, который имеет одинаковый шаблон. Тяжело на этом смотреть, когда знаешь что такое цикл.
Попробовал сделать циклом, но результаты выводятся не всегда, асинхронно не работает.
var json = {
currency: {
GBP: {
current: 'https://api.fixer.io/latest?base=GBP&symbols=USD',
last: 'https://api.fixer.io/'+ last.year +'-'+ last.month() +'-'+ last.day +'?base=GBP&symbols=USD'
},
EUR: {
current: 'https://api.fixer.io/latest?base=EUR&symbols=USD,JPY,RUB',
last: 'https://api.fixer.io/'+ last.year +'-'+ last.month() +'-'+ last.day +'?base=EUR&symbols=USD,JPY,RUB'
},
USD: {
current: 'https://api.fixer.io/latest?base=USD&symbols=JPY,CHF,CAD,RUB',
last: 'https://api.fixer.io/'+ last.year +'-'+ last.month() +'-'+ last.day +'?base=USD&symbols=JPY,CHF,CAD,RUB'
},
AUD: {
current: 'https://api.fixer.io/latest?base=AUD&symbols=USD',
last: 'https://api.fixer.io/'+ last.year +'-'+ last.month() +'-'+ last.day +'?base=AUD&symbols=USD'
},
NZD: {
current: 'https://api.fixer.io/latest?base=NZD&symbols=USD',
last: 'https://api.fixer.io/'+ last.year +'-'+ last.month() +'-'+ last.day +'?base=NZD&symbols=USD'
}
}
};
var currency = [];
var last = [];
$.when(
getAllCurrency()
).then(function() {
setResult($('.list.currency').createHead(), $.extend(true, currency, last));
});
function getAllCurrency() {
for (var prop in json.currency) {
getCurrency(prop);
}
};
function getCurrency(valute) {
$.ajax({
type: 'GET',
url: json.currency[valute].current,
dataType: 'json',
success: function(data) {
if (!data) return false;
for (var prop in data.rates) {
var options = {
name: valute + '/' + prop,
price: data.rates[prop]
};
currency.push(options);
}
}
});
$.ajax({
type: 'GET',
url: json.currency[valute].last,
dataType: 'json',
success: function(data) {
if (!data) return false;
for (var prop in data.rates) {
var options = {
change: data.rates[prop]
};
last.push(options);
}
}
});
};
Идея была в том, чтобы после выполнения функции getAllCurrency выполнялось тело .then()
Итог: подскажите, пожалуйста, как это запихнуть правильно в цикл, чтобы выводить результат после успешного выполнения всех запросов, спасибо!
Демо страника