更改Javascript同步

更改Javascript同步,javascript,promise,Javascript,Promise,我有一个名为dataCollect的函数,它在一个API中收集数据。我需要在每次调用之间留出1秒的间隔,因为API不会在很短的时间内响应多次调用 我还有一个名为centerArray的数组,其中包含我必须传递给API的数据,每个交互都传递不同的数据 我承诺在完成API数据收集的循环时,控制台会显示一条消息“finish”,即我的代码保持同步。但这种情况不会发生,在终止交互之前,“finish”消息以异步方式出现 const listMakers = () => { cons

我有一个名为dataCollect的函数,它在一个API中收集数据。我需要在每次调用之间留出1秒的间隔,因为API不会在很短的时间内响应多次调用

我还有一个名为centerArray的数组,其中包含我必须传递给API的数据,每个交互都传递不同的数据

我承诺在完成API数据收集的循环时,控制台会显示一条消息“finish”,即我的代码保持同步。但这种情况不会发生,在终止交互之前,“finish”消息以异步方式出现

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秒的间隔进行API调用,并确定是否所有调用都已完成

代码中的主要错误是以下部分:

centerArray.forEach((元素,idx)=>{
设置间隔(()=>{
数据收集(元素)
}, 1000);
});
在这里,您希望forEach的
回调将在给定的间隔内执行。但这不是异步代码在JS中使用
.forEach
.map
的方式。在这种情况下,数组将被同步迭代,所有回调将立即启动。 为了解决这个问题,我建议您采用以下代码结构:

//包含数据的数组
常量中心数组=[1,2,3,4,5,6,7,8,9,10];
//可以等待的等待函数
const wait=(ms=1000)=>新承诺(resolve=>setTimeout(resolve,ms));
//返回承诺的异步方法
//它可以是类似axios(url)的API调用,在您的情况下,它只是dataCollect(),
//我不知道你是否用这个方法做了一些异步的事情
const doRequest=requestNumber=>新承诺(解析=>{
log(`${requestNumber}请求完成`);
解决();
});
//您需要使用旧的good“for of”而不是“forEach”
//将此方法标记为“async”将使其返回承诺
const run=async()=>{
用于(centerArray的常数i){
等待多勒奎斯特(i);
//或等待收集数据();
等待等待;
}
};
然后(()=>console.log(“全部完成”);
运行代码以查看输出:

1请求已完成
...
10.请求已完成
全部完成
编辑: 现在我可以看到您的
dataCollect
方法和另一个重要错误:

功能数据采集(位置){
...
service.nearbySearch(请求、功能(结果、状态){
//您需要等待此回调
if(status==google.maps.places.PlacesServiceStatus.OK){
markerary.push(结果)
}
})
return markerary;//立即执行
}
重写上述
doRequest
示例中的方法,以便等待:

异步函数数据收集(位置){ 返回新承诺(解决=>{ ... service.nearbySearch(请求、功能(结果、状态){ if(status==google.maps.places.PlacesServiceStatus.OK){ markerary.push(结果) } 解决(Markerary); }) } }
如果我理解您的问题正确,您希望以1秒的间隔进行API调用,并确定是否完成了所有调用

代码中的主要错误是以下部分:

centerArray.forEach((元素,idx)=>{
设置间隔(()=>{
数据收集(元素)
}, 1000);
});
在这里,您期望
forEach
的回调将在给定的间隔内执行。但这不是异步代码在JS中使用
.forEach
.map
的工作方式。在这种情况下,数组将同步迭代,所有回调将立即启动。 为了解决这个问题,我建议您采用以下代码结构:

//包含数据的数组
常量中心数组=[1,2,3,4,5,6,7,8,9,10];
//可以等待的等待函数
const wait=(ms=1000)=>新承诺(resolve=>setTimeout(resolve,ms));
//返回承诺的异步方法
//它可以是类似axios(url)的API调用,在您的情况下,它只是dataCollect(),
//我不知道你是否用这个方法做了一些异步的事情
const doRequest=requestNumber=>新承诺(解析=>{
log(`${requestNumber}请求完成`);
解决();
});
//您需要使用旧的good“for of”而不是“forEach”
//将此方法标记为“async”将使其返回承诺
const run=async()=>{
用于(centerArray的常数i){
等待多勒奎斯特(i);
//或等待收集数据();
等待等待;
}
};
然后(()=>console.log(“全部完成”);
运行代码以查看输出:

1请求已完成
...
10.请求已完成
全部完成
编辑: 现在我可以看到您的
dataCollect
方法和另一个重要错误:

功能数据采集(位置){
...
service.nearbySearch(请求、功能(结果、状态){
//您需要等待此回调
if(status==google.maps.places.PlacesServiceStatus.OK){
markerary.push(结果)
}
})
return markerary;//立即执行
}
重写上述
doRequest
示例中的方法,以便等待:

异步函数数据收集(位置){ 返回新承诺(解决=>{ ... service.nearbySearch(请求、功能(结果、状态){ if(status==google.maps.places.PlacesServiceStatus.OK){ markerary.push(结果) } 解决(Markerary); }) } }
我认为使用
callback
作为Promise构造函数包装的执行器函数的名称不是一个好主意。它会立即执行,例如