Обработка нескольких асинхронных вызовов внутри цикла for

#javascript #vue.js #asynchronous

#javascript #vue.js #асинхронный

Вопрос:

У меня есть цикл javascript for, в котором я вызываю функцию для каждой привязки к широте-lng, внутри этой функции я выполняю ТРИ асинхронных вызова API Google maps Places, после выполнения всех трех вызовов я окрашиваю границы в зеленый цвет.

Проблема в том, что мой цикл for выполняется синхронно, и все границы окрашиваются в зеленый цвет за один тик вместо того, чтобы требовать возобновления всех трех асинхронных вызовов.

Как я могу сделать это так, чтобы цикл for ожидал выполнения асинхронных вызовов перед переходом к следующей итерации?

Мой код:

 async startScrapingGridLoop()
    {
        const self = this;

        for (var i = 0; i < self.zoneBoundaries.length; i  )
        {
            //Multiple async calls
            await self.scrapeCellWithPlaces(self.zoneBoundaries[i]);
            //After all three async calls end I want to color the bound green
            let currentPolygon = self.polygonsArray[i];
            currentPolygon.setOptions({fillColor: 'green', fillOpacity:0.6});

        }
    },

async scrapeCellWithPlaces(zoneBoundaries)
    {
        const self = this;
        var request = {};
        var bounds = new google.maps.LatLngBounds(new google.maps.LatLng({ lat:zoneBoundaries.sw.lat(), lng:zoneBoundaries.sw.lng() }), new google.maps.LatLng({ lat:zoneBoundaries.ne.lat(), lng:zoneBoundaries.ne.lng() }));


        for (var i = 0; i < self.types.length; i  )
        {
                
                
            request = { bounds: bounds, type: self.types[i] };
                
            self.placesService.nearbySearch(request, self.scrapeCellWithPlacesCallback);
            console.log('Scraping bounds for ' self.types[i]);
        }

    },

scrapeCellWithPlacesCallback(results, status, pagination)
    {
        const self = this;
         
        if (status == google.maps.places.PlacesServiceStatus.OK)
        {      
            for (var i = 0; i < results.length; i  )
            {
                self.results.push(results[i]);
            } 

            //self.setPlacesMarker(self.results);
            //self.fitPlacesBounds(self.results);
            
            if (pagination.hasNextPage)
            {
                console.log('fetching next set of sets');
                sleep:3;
                pagination.nextPage();

                for (var i = 0; i < results.length; i  )
                {
                    self.results.push(result[i]);
                } 
            }
        }
        console.log(self.results);
    },

  

Ответ №1:

Вы могли бы попытаться извлечь все необходимые данные перед их обработкой, используя Promise.all .

Например.:

 async function scrapeGrid() {
  let boundaries = [];
  this.zoneBoundaries.forEach(boundary => boundaries.push(scrapeCellWithPlaces(boundary)));
  const polygons = await Promise.all(boundaries);
}
  

Ответ №2:

Вы должны преобразовать версию обратного вызова nearbySearch в версию promise, чтобы ожидание по обещанию работало

 async startScrapingGridLoop() {
  const self = this

  for (var i = 0; i < self.zoneBoundaries.length; i  ) {
    //Multiple async calls
    await self.scrapeCellWithPlaces(self.zoneBoundaries[i])
    //After all three async calls end I want to color the bound green
    let currentPolygon = self.polygonsArray[i]
    currentPolygon.setOptions({ fillColor: "green", fillOpacity: 0.6 })
  }
},

async scrapeCellWithPlaces(zoneBoundaries) {
  const self = this
  var request = {}
  var bounds = new google.maps.LatLngBounds(
    new google.maps.LatLng({
      lat: zoneBoundaries.sw.lat(),
      lng: zoneBoundaries.sw.lng(),
    }),
    new google.maps.LatLng({
      lat: zoneBoundaries.ne.lat(),
      lng: zoneBoundaries.ne.lng(),
    })
  )

  for (var i = 0; i < self.types.length; i  ) {
    request = { bounds: bounds, type: self.types[i] }

    await self.nearbySearchPromise(request);
    console.log("Scraping bounds for "   self.types[i])
  }
},

nearbySearchPromise(request) {
  const self = this

  return new Promise((resolve) => {
    self.placesService.nearbySearch(request, (results, status, pagination) => {
      if (status == google.maps.places.PlacesServiceStatus.OK) {
        for (var i = 0; i < results.length; i  ) {
          self.results.push(results[i])
        }
    
        //self.setPlacesMarker(self.results);
        //self.fitPlacesBounds(self.results);
    
        if (pagination.hasNextPage) {
          console.log("fetching next set of sets")
          sleep: 3
          pagination.nextPage()
    
          for (var i = 0; i < results.length; i  ) {
            self.results.push(result[i])
          }
        }
      }
      console.log(self.results)

      resolve()
    })
  })
}
  

Комментарии:

1. Пробовал, но все равно ничего, все полигоны на карте становятся зелеными одновременно, похоже, что теперь следующий вызов ожидает завершения предыдущего перед выполнением следующего. Я отредактировал OP, чтобы показать новый код

2. @gabogabans вам также следует добавить подробную информацию о scrapeCellWithPlacesCallback

3. Добавлено в OP, извините

4. @gabogabans Я обновил ответ, вы могли бы посмотреть и попробовать