Чем заменить 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 запроса с массивом данных.

→ Ссылка
Автор решения: Leonid

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

→ Ссылка