Изменить Javascript Синхронный - PullRequest
0 голосов
/ 26 января 2020

У меня есть функция dataCollect, которая собирает данные в одном API. Мне нужно сделать интервал 1 секунда между каждым вызванным, потому что API не отвечает многим вызванным в маленьком временном пространстве.

У меня также есть один массив под названием centerArray с данными, которые я должен передать API, и при каждом взаимодействии я передаю разные данные.

Я выполнил Обещание, когда по окончании sh l oop собирая данные API, он показывает в консоли сообщение «fini sh», то есть мой код остается синхронным. Но этого не происходит, сообщение «fini sh» появляется асинхронным способом, перед тем как прекратить взаимодействие.

const listMakers = () => {
        const callback = (resolve, reject) => {
            centerArray.forEach((element, idx) => {
                setInterval(() => {
                    dataCollect(element)
                }, 1000);
            });
        }
        return new Promise(callback)
    }

    listMakers().finally(console.log('finish'))

function dataCollect(location) {
        markerArray= [];
        var request = {
            location: location,
            radius: raio,
            type: ['restaurant']
        }

        service = new google.maps.places.PlacesService(map);
        service.nearbySearch(request, function(results, status) {

           if (status == google.maps.places.PlacesServiceStatus.OK) {
              markerArray.push(results)
           }
        })
        return markerArray;
}

1 Ответ

2 голосов
/ 27 января 2020

Если я правильно понял ваш вопрос, вы хотите сделать вызовы API с интервалом 1 сек c и определить, все ли вызовы выполнены.

Основная ошибка в вашем коде - следующая часть:

centerArray.forEach((element, idx) => {
                setInterval(() => {
                    dataCollect(element)
                }, 1000);
            });

Здесь вы ожидаете, что обратный вызов forEach будет выполнен с заданным интервалом. Но это не так, как асин c код работает в JS с .forEach или .map, например. В этом случае массив будет повторяться синхронно и все обратные вызовы начнутся немедленно. Чтобы решить эту проблему, я предлагаю вам следующую структуру кода:

// some array with your data
const centerArray = [1,2,3,4,5,6,7,8,9,10];

//waiting function that can be awaited
const wait = (ms = 1000) => new Promise(resolve => setTimeout(resolve, ms));

// your asynchronous method that returns Promise
// it can be an API call like axios(url), in your case it is just dataCollect(), 
// i dont know if you do some async stuff in this method or not
const doRequest = requestNumber => new Promise(resolve => {
    console.log(`${requestNumber} request done`);
    resolve();
});

// you need to use old good "for of" instead of "forEach"
// marking this method with "async" makes it return Promise
const run = async () => {
    for (const i of centerArray) {
        await doRequest(i);
        // or await collectData();  
        await wait();
    }
};
run().then(() => console.log("all done"));

Запустите код, чтобы увидеть вывод:

1 request done
...
10 request done
all done

РЕДАКТИРОВАТЬ : Теперь я могу видеть вас dataCollect метод и другая важная ошибка:

function dataCollect(location) {
     ...
     service.nearbySearch(request, function(results, status) {
           // you need to wait for this callback
           if (status == google.maps.places.PlacesServiceStatus.OK) {
              markerArray.push(results)
           }
        })
     return markerArray; //this executes immediately 
}

Перепишите метод, как в приведенном выше примере doRequest, чтобы вы могли дождаться его:

async function dataCollect(location) {
     return new Promise(resolve => {
          ...
          service.nearbySearch(request, function(results, status) {
               if (status == google.maps.places.PlacesServiceStatus.OK) {
                   markerArray.push(results)
                }
               resolve(markerArray);
          })
     }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...