#javascript #jquery #asynchronous #synchronous
#javascript #jquery #асинхронный #синхронный
Вопрос:
Я новичок в Javascript и испытываю серьезные проблемы, пытаясь понять асинхронный код и как им управлять. Моя главная проблема, из-за которой все это началось, заключается в том, что я пытаюсь прочитать объект JSON (в quotesList) с помощью http-запроса и сохранить его в глобальном для последующего использования. При попытке запустить мой код, поскольку он выполняется асинхронно, объект будет отображаться в других функциях как неопределенный, поскольку функция, определяющая его, к тому времени еще не завершилась. Я просто не знаю, как это решить.
Любая помощь приветствуется!
let requestURL = 'https://gist.githubusercontent.com/nasrulhazim/54b659e43b1035215cd0ba1d4577ee80/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json'
var quotesList;
var x = 5;
var colors = [
"EE6D51",
"72EE51",
"E7EA27",
"FFA428",
"28FF4F",
"456CFC",
"A645FC",
"FC459B",
"FC458A",
"FE2842",
"28FED4"
]
function getQuotes() {
let request = new XMLHttpRequest();
request.open('GET', requestURL);
request.responseType = 'json';
request.send();
request.onload = function() {
quotesList = request.response;
if (quotesList == null) {
alert("Something's definitely wrong here...");
}
console.log('quotesList');
console.log(quotesList);
}
}
function populate() {
var x = Math.floor(Math.random() * Math.floor(quotesList.quotes.length));
document.getElementById('quote').innerHTML = quotesList.quotes[x].quote;
document.getElementById('author').innerHTML = quotesList.quotes[x].author;
}
$(function() {
getQuotes()
populate
while(($('.container strong ').height() >= 300)) {
$('.container strong').css('font-size', (parseInt($('.container strong').css('font-size')) - 10.5) "px");
$('.container h3').css('font-size', (parseInt($('.container h3').css('font-size')) - 7.5) "px");
}
});
Комментарии:
1. » сохраните это в глобальном для последующего использования». — нет. Просто вызовите
populate(quotesList)
изonload
обратного вызова напрямую и передайте значение в качестве аргумента. Не используйте глобальную переменную. (И, вероятно, вам придется переместить код форматирования высоты вpopulate
)2. Но разве мне не нужно было бы получать кавычки каждый раз, когда я хочу заполнить html-элемент? Я хочу, чтобы список цитат был доступен, когда пользователь выбирает «следующую цитату». Не было бы сложнее иметь локальный?
3. Извините, было неясно, что пользователь может выбрать «следующую цитату». В этом случае вы должны
populate
отобразить одну цитату и кнопку для отображения следующей, чтобы прослушиватель событий на следующей кнопкеquotesList
также имел доступ к . Для этого не обязательно быть глобальным.
Ответ №1:
Вам следует подробнее прочитать о promises, async / await
Вот ваш рабочий код (это работает только в новых браузерах (например, без IE), иначе вам понадобится babel для переноса кода async await)
let requestURL = 'https://gist.githubusercontent.com/nasrulhazim/54b659e43b1035215cd0ba1d4577ee80/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json'
var quotesList;
var x = 5;
var colors = [
"EE6D51",
"72EE51",
"E7EA27",
"FFA428",
"28FF4F",
"456CFC",
"A645FC",
"FC459B",
"FC458A",
"FE2842",
"28FED4"
]
function getQuotes() {
return new Promise(function (resolve, reject) {
let request = new XMLHttpRequest();
request.open('GET', requestURL);
request.responseType = 'json';
request.onload = function() {
let status = request.status;
quotesList = request.response;
if (quotesList == null) {
alert("Something's definitely wrong here...");
}
console.log('quotesList');
console.log(quotesList);
if (status == 200) {
resolve(request.response);
} else {
reject(status);
}
}
request.send();
});
}
function populate() {
var x = Math.floor(Math.random() * Math.floor(quotesList.quotes.length));
document.getElementById('quote').innerHTML = quotesList.quotes[x].quote;
document.getElementById('author').innerHTML = uotesList.quotes[x].author;
}
async function start(){
await getQuotes();
populate();
}
$(function() {
start();
while(($('.container strong ').height() >= 300)) {
$('.container strong').css('font-size', (parseInt($('.container strong').css('font-size')) - 10.5) "px");
$('.container h3').css('font-size', (parseInt($('.container h3').css('font-size')) - 7.5) "px");
}
});