-1

Как переписать этот код без 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 все работает как мне нужно, но это очень плохая практика и так не рекомендуется делать. Прошу, помогите разобраться

Jesse
  • 74

2 Answers2

2

Буду краток. Можно переписать с помощью async/await. Для подробностей либо в поисковик, потому что тема очень обширна, чтобы её писать в ответ, либо сюда: Как вернуть значение из события или из функции обратного вызова? Или хотя бы дождаться их окончания

Там тоже есть освещение этого синтаксиса, но очень скудное и вряд что-то будет понятно.


Но на самом деле здесь не нужен ajax запрос в цикле. Достаточно собрать все данные и всем скопом одним запросом послать их на сервер для обработки. И так же потом обработать результат, полученный от сервера. Достаточно одного ajax запроса с массивом данных.

2

Можно создать асинхронный итерируемый объект с помощью асинхронного генератора, а затем пройтись по нему в асинхронном цикле 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);
}

})()

Leonid
  • 5,797