У меня есть API, из которого мне нужно запросить N страниц данных. Потому что я не хочу перегружать API, я хочу делать это последовательно и без блокировки основного потока.
Код будет примерно таким:
var res = []; // all data from api
var totalPages = 10;
var pageSize = 100;
for (let page = 0; page < totalPages; page++) {
// load using jQuery ajax request
$.get('api.php', { page: page, page_size: pageSize }, function(result) {
res.push(...result); // add data to resulting array
});
}
Но у этого подхода есть несколько проблем:
res
в какой-то другой код, который в этом нуждается.Есть ли способ исправить эти проблемы без использования каких-то сторонних библиотек или промисов? Просто старый ванильный javascript. Извините, если что-то покажется непонятным, я не очень разбираюсь в js.
Зачем вам все эти данные сразу? Вы должны реализовать пагинацию
@ChrisG, не могли бы вы опубликовать пример такой очереди? Что касается обещаний, могу ли я быть уверен, что по крайней мере у 99% пользователей есть браузеры, которые их поддерживают?
@proofzy, даже если я использую его прямо в обратном вызове результата, это ничего не изменит в моем вопросе.
Обещает находятся простой ванильный javascript.
@Bergi per caniuse.com/async-функции кажется, что более 1% активных пользователей не поддерживают обещания, в том числе 0,45% хрома, 0,5% IE и 0,37% края.
@maxpovver Если вы хотите использовать только функции, которые поддерживают более 1% используемых браузеров, напишите то, что вы имеете в виду, а не «ванильный javascript» (что означает просто js без библиотек). Однако вы уже используете jQuery, так что это все равно не ваниль. И jQuery приносит с собой реализацию обещаний! Это не правильный полифилл, но его все еще можно использовать. Вы определенно должны использовать обещания здесь.
Здесь вы можете использовать простую рекурсию, например:
var res = []; // all data from api
var totalPages = 10;
var pageSize = 100;
const loader = page => {
// load using jQuery ajax request
$.get('api.php', { page: page, page_size: pageSize }, function(result) {
res.push(...result); // add data to resulting array
if (page < totalPages)
loader(++page)
else
console.info('DONE!');
});
}
loader(0);
Можно улучшить ответ, также показав, как это сделать с помощью обещанного get()
, который затем можно использовать внутри цикла async
for и awaiting
запросов последовательно. Но да, это классический способ старой школы, который иногда полезен в более сложном коде, с которым промисы не справляются.
@slebetman Требование было without using promises
, поэтому async/await
отсутствует. Но вы можете написать свой ответ, если считаете, что он будет полезен.
спасибо @syduki! это то, что мне было нужно. Было бы здорово также увидеть версию обещаний @slebetman
Если я напишу свой собственный ответ, он просто будет включать полную копию/вставку вашего ответа в качестве первой его части. Было бы лучше просто избежать этого и добавить сюда
Реализовать очередь. Кроме того, промисы хороши по сравнению с обратными вызовами, и нет причин не использовать их.