【发布时间】:2018-02-21 09:11:49
【问题描述】:
我有一个用户数据库,我想为他们设置经度和纬度。但是,在 6 次以上调用后,我收到错误 400,请求错误。我想这是因为我对 google maps API 的调用太多,所以决定创建一个 setTimeout 函数,所以我会每 1 秒获取一次坐标。
然后我发现我的 forEach 行为很奇怪。这是代码,然后我将解释问题所在。 (我认为相关的部分代码)
let noOfSuccess = 0;
let noCoords = 0;
let forEachPromise = new Promise((resolve, reject) => {
arr.forEach(function (user) {
console.log('street', user.street)
let coordPromise = new Promise((resolve, reject) => {
let street = user.street;
let city = user.city;
let address = street.concat(', ').concat(city);
const url = `https://maps.googleapis.com/maps/api/geocode/json?address=${address}&key=APIKEY`;
setTimeout(function () {
let coords = axios.get(url).then((response) => {
return response;
})
resolve(coords);
}, 1000);
})
coordPromise.then(response => {
if (response.data.results[0].types == "street_address") {
console.log('adres', response.data.results[0].formatted_address)
arrSucc.push(response.data.results[0].formatted_address);
noOfSuccess++;
} else {
arrFail.push(response.data.results[0].formatted_address);
noCoords++;
}
console.log('coordResp', 'succ', noOfSuccess, 'fail', noCoords)
})
});
我希望它如何工作: 我从数据库中获取用户,我 console.log 街道名称进行测试。然后我创建一个承诺。在承诺中,我等待 1 秒来调用谷歌 API。收到回复后,我解决了这个承诺。 然后我接受响应,做一些检查并 console.log 发生了什么,无论是成功还是失败。然后我去下一个用户。 然后首选输出: 用户街道 -> google API 调用 -> 记录成功或失败 对所有用户重复。
但是发生的事情是: 它记录用户的所有街道,然后进入承诺,1 秒后立即对 API 进行所有调用,而无需等待 1 秒,然后记录每个用户是否成功或失败。外观:
now listening for requests
street Kwiatowa 40
street Kwiatowa 40
street Kwiatowa 43
street Kwiatowa 36
street Kwiatowa 27
street Kwiatowa 42
street Kwiatowa 29
street Kwiatowa 45
(node:5800) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: Request failed with status code 400
(node:5800) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
adres Kwiatowa 36, 02-579 Warszawa, Poland
coordResp succ 1 fail 0
adres Kwiatowa 43, 02-579 Warszawa, Poland
coordResp succ 2 fail 0
adres Kwiatowa 40, 02-579 Warszawa, Poland
coordResp succ 3 fail 0
adres Kwiatowa 27, 02-579 Warszawa, Poland
coordResp succ 4 fail 0
adres Kwiatowa 29, Radom, Poland
coordResp succ 5 fail 0
adres Kwiatowa 42, 02-579 Warszawa, Poland
coordResp succ 6 fail 0
adres Kwiatowa 40, 02-579 Warszawa, Poland
coordResp succ 7 fail 0
我做错了什么?我理解 Promise 或 forEach 循环是否有问题?
【问题讨论】:
-
Don't use
forEachwith promises(或者,一般来说更好)。
标签: javascript node.js asynchronous