Чем заменить async: false?
Как переписать этот код без async: false
$('.cart-item').removeClass('in-cart');
cart_list.map(item => {
$(`.cart-item[data-cart-id="${item.id}"]`).addClass('in-cart');
if($(`.cart-item[data-cart-id="${item.id}"]`).length == 0) {
$.ajax({
url: '/core/action/cart/req.php',
type: 'POST',
async: false,
data: {
items: item
},
success: function(data) {
cart.render(data);
}
})
}
});
$('.cart-item').each(function() {
if(!$(this).hasClass('in-cart')) {
$(this).addClass('remove');
}
});
Как ожидать ответ от ajax прежде чем пойдет новая итерация ? С параметром async: false все работает как мне нужно, но это очень плохая практика и так не рекомендуется делать. Прошу, помогите разобраться
Ответы (2 шт):
Буду краток. Можно переписать с помощью async/await. Для подробностей либо в поисковик, потому что тема очень обширна, чтобы её писать в ответ, либо сюда: Как вернуть значение из события или из функции обратного вызова? Или хотя бы дождаться их окончания
Там тоже есть освещение этого синтаксиса, но очень скудное и вряд что-то будет понятно.
Но на самом деле здесь не нужен ajax запрос в цикле. Достаточно собрать все данные и всем скопом одним запросом послать их на сервер для обработки. И так же потом обработать результат, полученный от сервера. Достаточно одного ajax запроса с массивом данных.
Можно создать асинхронный итерируемый объект с помощью асинхронного генератора, а затем пройтись по нему в асинхронном цикле for/await.
(async function addImages(){
let image_urls = [
"https://image.freepik.com/free-vector/linear-flat-wedding-monograms_52683-64319.jpg",
"https://image.freepik.com/free-vector/flat-car-poster-with-photo-horizontal_52683-64510.jpg"
];
async function* loadImages(urls){
for(let url of urls){
console.log('loading: ' + image_urls.indexOf(url));
let image = new Image();
image.src = url;
image.onload = yield function(container){
console.log(image_urls.indexOf(url) + ' has loaded');
container.append(image);
}
}
}
for await (let f of loadImages(image_urls)){
f(document.body);
}
})()
Если буквально по теме запроса данных, то реализация через fetch:
const URLS = [
'https://jsonplaceholder.typicode.com/users/1',
'https://jsonplaceholder.typicode.com/users/2'
];
(async function placeData(){
async function* getJSON(urls){
for(let url of urls){
console.log('Sending request for user ' + (URLS.indexOf(url) + 1));
let data = await fetch(url);
console.log('Waiting for user ' + (URLS.indexOf(url) + 1));
yield data.json();
}
}
for await(let json of getJSON(URLS)){
console.log(json);
}
})()