Node.js:如何使用异步/等待处理HTTP请求限制错误?

时间:2019-02-04 16:55:09

标签: javascript node.js http async-await

我正在尝试构建一个搜索API,该API将位置作为参数并返回该位置的纬度和经度。 我正在使用http://geocode.xyz来获取位置的详细信息。 例如 : https://geocode.xyz/?locate=Warsaw,Poland&json=1 这将返回该位置所需的纬度和经度。

这是我的代码段:

const url = 'https://geocode.xyz/?locate=Warsaw,Poland&json=1';
const getData = async url => {
try {
  const response = await fetch(url);
  const json = await response.json();
  console.log(json);
} catch (error) {
  console.log(error);
}
};
getData(url);

有了这个,这就是我看到的错误:

node geocode.js
{success: false, error: { code: '006', message: 'Request Throttled.'}}

我猜这是因为我需要限制达到API https://geocode.xyz的请求数量。我不确定如何在异步/等待中使用速率限制器。任何帮助将不胜感激。

编辑: 根据以下答案,我仍然看到“请求已限制”

var request = require('request');
const fetch = require("node-fetch");

const requester = {
    lastRequest: new Date(),
    makeRequest: async function(url) {
        // first check when last request was made
        var timeSinceLast = (new Date()).getTime() - this.lastRequest.getTime();
        if (timeSinceLast < 2000) {
            this.lastRequest = new Date(this.lastRequest.getTime() + (2000 - timeSinceLast));
            await new Promise(resolve => setTimeout(resolve, 2000-timeSinceLast));
          //  await new Promise(resolve => setTimeout(resolve, timeSinceLast));
        }
        const response = await fetch(url);
        const json = await response.json();
        return json;
    }
};
requester.makeRequest('https://geocode.xyz/?locate=Warsaw,Poland&json=1')
.then(console.log)

我仍然遇到相同的错误:

{ success: false, error: { code: '006', message: 'Request Throttled.' } }

是因为geocode pricing吗?有什么方法可以限制用户端的请求速率?

1 个答案:

答案 0 :(得分:1)

您可以创建一个用于发送所有请求的对象,并且该对象可以跟踪上次发出请求的时间。例如

const requester = {
    lastRequest: new Date(2000,0,1),
    makeRequest: async function (url) {
        // first check when last request was made
        var timeSinceLast = (new Date()).getTime() - this.lastRequest.getTime();
        this.lastRequest = new Date();
        if (timeSinceLast < 1000) {
            this.lastRequest = new Date(this.lastRequest.getTime() + (1000 - timeSinceLast));
            await new Promise(resolve => setTimeout(resolve, 1000-timeSinceLast));
        }

        // make request here and return result
        const response = await fetch(url);
        const json = await response.json();
        return json;
    }
};

https://jsfiddle.net/3k7b0grd/

如果您使用requester.request,它只能让您每秒发出一次请求,并且等待足够长的时间(即使是连续的请求)也要遵守该速率限制