- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
到目前为止,这是我的代码:
const allRows = [];
async function fileToLines(file) {
return new Promise((resolve, reject) => {
reader = new FileReader();
reader.onload = function(e) {
parsedLines = e.target.result.split(/\r|\n|\r\n/);
resolve(parsedLines);
};
reader.readAsText(file);
});
}
document
.getElementById('fileInput')
.addEventListener('change', async function(e) {
var file = e.target.files[0];
if (file != undefined) {
fileToLines(file).then( async id => {
console.log(id)
console.log(parsedLines)
console.log(typeof id);
var idInt = id.map(Number);
var idFiltered = id.filter(function(v){return v!==''});
console.log(idFiltered)
for(let id of idFiltered) {
const row = await getRelease(id);
allRows.push(row);
}
download();
});
}
});
function getRelease(idFiltered) {
return fetch(`https://api.***.com/releases/${idFiltered}`, {
headers: {
'User-Agent': '***/0.1',
},
})
.then(response => response.json())
.then(data => {
if (data.message === 'Release not found.') {
return { error: `Release with ID ${idFiltered} does not exist` };
} else {
const id = data.id;
const delimiter = document.getElementById("delimiter").value || "|";
const artists = data.artists ? data.artists.map(artist => artist.name) : [];
const barcode = data.identifiers.filter(id => id.type === 'Barcode')
.map(barcode => barcode.value);
var formattedBarcode = barcode.join(delimiter);
const country = data.country || 'Unknown';
const genres = data.genres || [];
const formattedGenres = genres.join(delimiter);
const labels = data.labels ? data.labels.map(label => label.name) : [];
const formattedLabels = labels.join(delimiter);
const catno = data.labels ? data.labels.map(catno => catno.catno) : [];
const formattedCatNo = catno.join(delimiter);
const styles = data.styles || [];
const formattedStyles = styles.join(delimiter);
const tracklist = data.tracklist ? data.tracklist
.map(track => track.title) : [];
const formattedTracklist = tracklist.join(delimiter);
const year = data.year || 'Unknown';
const format = data.formats ? data.formats.map(format => format.name) : [];
const qty = data.formats ? data.formats.map(format => format.qty) : [];
const descriptions = data.formats ? data.formats
.map(descriptions => descriptions.descriptions) : [];
const preformattedDescriptions = descriptions.toString()
.replace('"','""').replace(/,/g, ', ');
const formattedDescriptions = '"' + preformattedDescriptions + '"';
return [idFiltered,
artists,
format,
qty,
formattedDescriptions,
formattedLabels,
formattedCatNo,
country,
year,
formattedGenres,
formattedStyles,
formattedBarcode,
formattedTracklist
];
}
});
}
function download() {
const ROW_NAMES = [
"release_id",
"artist",
"format",
"qty",
"format descriptions",
"label",
"catno",
"country",
"year",
"genres",
"styles",
"barcode",
"tracklist"
];
var csvContent = "data:text/csv;charset=utf-8,"
+ ROW_NAMES + "\n" + allRows.map(e => e.join(",")).join("\n");
console.log(csvContent);
var encodedUri = encodeURI(csvContent);
var link = document.createElement("a");
link.setAttribute("href", encodedUri);
link.setAttribute("download", "my_data.csv");
document.body.appendChild(link); // Required for FF
link.click();
}
当我在 2.5 年前(!)尝试破解这个问题时,有人告诉我最简单的方法“是维护一个 promise 链来跟踪请求”,就像这样......
const timer = ms => new Promise(resolve => setTimeout(resolve, ms));
let requests = Promise.resolve();
function getRelease(id) {
const apiCall = requests.then(() =>
fetch(`https://api.***.com/releases/${id}`, {
headers: {
'User-Agent': '***/0.1',
}
})
);
// add to chain / queue
requests = apiCall.then(response =>
+response.headers.get("X-***-Ratelimit-Remaining") <= 1 && timer(60 * 1000)
);
return apiCall
.then(response => response.json())
.then(parseReleaseData);
}
建议此代码的人评论...
Now one request will be done after another, and if the rate limit gets reached it waits a minute.
You might want to retry in case of a rate limiting error. You could also add multiple promise queues to allow for higher throughput.
似乎我之前尝试过时,它在进行任何调用之前设置了 60 秒的延迟?我想我想再次尝试这种方法,但我不确定如何编码。比如,我不确定 const apiCall = requests.then(() =>
如何适合我当前的代码。我可以看到建议的代码实际上返回“apiCall”,而我的方法设置为返回所有单独的数据字段,所以我不确定如何在那里进行。这似乎是从主机获取 Ratelimit
并根据需要设置超时的好方法,但是我真的不确定从哪里开始。有什么帮助吗?
编辑:我一直在尝试这样做,但还是不行:
const timer = ms => new Promise(resolve => setTimeout(resolve, ms));
const createThrottler = (rateLimit) => {
let requestTimestamp = 0;
return (requestHandler) => {
return async (...params) => {
const currentTimestamp = Math.floor(Date.now() / 1000);
if (currentTimestamp < requestTimestamp + rateLimit) {
await timer(rateLimit - (currentTimestamp - requestTimestamp))
}
requestTimestamp = Math.floor(Date.now() / 1000);
return await requestHandler(...params);
}
}
}
const throttle = createThrottler(2500);
const throttleFetch = throttle(fetch);
Edit2:我想知道是否有问题,我将这一行注释掉了:
const rateLimit = Math.floor((60/response.headers.get("X-Discogs-Ratelimit-Remaining")) * 1000);
所以我试着取消评论,但现在我明白了
Uncaught ReferenceError:
response
is not defined
Edit3:我得到了让 createThrottler()
函数正常工作的建议:-
const rateLimit = 2500;
const timer = ms => new Promise(resolve => setTimeout(resolve, ms));
const createThrottler = (rateLimit) => {
let requestTimestamp = 0;
return (requestHandler) => {
return async (...params) => {
const currentTimestamp = Number(Date.now());
if (currentTimestamp < requestTimestamp + rateLimit) {
const timeOut = rateLimit - (currentTimestamp - requestTimestamp);
requestTimestamp = Number(Date.now()) + timeOut;
await timer(timeOut)
}
requestTimestamp = Number(Date.now());
return await requestHandler(...params);
}
}
}
不能说我自己会解决这个问题,但我们做到了。所以现在我正在努力弄清楚如何以及在何处编码
const rateLimit = Math.floor((60 / response.headers.get("X-Discogs-Ratelimit-Remaining")) * 1000);
没有得到
Uncaught (in promise) ReferenceError: response is not defined
最佳答案
你看过去抖动了吗?
您可以像在任何定义的时间段内服务的 1 个调用一样对速率进行限制。将此视为量化。另一种方法是在延长的时间范围内对调用进行计数,然后无限期地或在定义的持续时间内阻止进一步的调用 - 这取决于您的首选用例。
通常,速率限制更多地与安全有关,第一个选项(在定义的时间段内服务一次调用)是恰当的。如果您为 Web API 执行此操作,您可能希望拒绝“过早”的请求,并使用适当的 HTTP 状态代码向请求者提供某种类型的反馈。
这里讨论了如何实现所有不同的选项:https://thoughtspile.github.io/2018/07/07/rate-limit-promises/
编辑:回应下面的 OP 评论并查看代码......我认为你想得太多了。
FWIW 我大部分时间都使用 debounce(相当于你的“ throttle ”),它的字面意思是 debounce(functionReference,timeoutInMilliseconds)。
代码是这样的
function debounce(func, waitFor) {
let timeout;
return (...args) => new Promise(resolve => {
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(() => resolve(func(...args)), waitFor);
});
}
将您的 throttle(fetch)
更改为我的 debounce(fetch,2500)
应该就足够了。你不需要在该行上进行赋值操作,只需调用它,或者编写另一个名为 debouncedFetch
的函数来封装它,并在任何需要的地方调用它。
关于javascript - 如何使用主机提供的速率限制来限制我的 JS API 获取请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70595420/
我有一个 ServiceBusQueue(SBQ),它获取大量消息负载。我有一个具有 accessRights(manage) 的 ServiceBusTrigger(SBT),它不断轮询来自 SBQ
在下面给出的结果集中,有 2 个唯一用户 (id),并且查询中可能会出现更多此类用户: 这是多连接查询: select id, name, col1Code, col2Code, col2Va
我正在用 Python 2.7.3 编写一个带有 GRequests 的小脚本和 lxml 可以让我从各种网站收集一些收藏卡价格并进行比较。问题是其中一个网站限制了请求的数量,如果我超过它,就会发回
我想知道何时实际使用删除级联或删除限制以及更新级联或更新限制。我对使用它们或在我的数据库中应用感到很困惑。 最佳答案 在外键约束上使用级联运算符是一个热门话题。 理论上,如果您知道删除父对象也将自动删
下面是我的输出,我只想显示那些重复的名字。每个名字都是飞行员,数字是飞行员驾驶的飞机类型。我想显示驾驶不止一架飞机的飞行员的姓名。我正在使用 sql*plus PIL_PILOTNAME
我正在评估不同的移动框架,我认为 nativescript 是一个不错的选择。但我不知道开发过程是否存在限制。例如,我对样式有限制(这并不重要),但我想知道将来我是否可以有限制并且不能使用某些 nat
我正在尝试使用 grails 数据绑定(bind)将一些表单参数映射到我的模型中,但我认为在映射嵌入式集合方面可能存在一些限制。 例如,如果我提交一些这样的参数,那么映射工作正常: //this wo
是否可以将 django 自过滤器起的时间限制为 7 天。如果日期超过 7 天,则不应用过滤器 最佳答案 timesince 的源代码位于 django/django/utils/timesince.
我想在我的网站上嵌入一个 PayPal 捐赠按钮。但问题是我住在伊朗——这个国家受到制裁,人们不使用国际银行账户或主要信用卡。 有什么想法吗?请帮忙! 问候 沮丧 最佳答案 您可以在伊朗境内使用为伊朗
这是我的查询 select PhoneNumber as _data,PhoneType as _type from contact_phonenumbers where ContactID = 3
这个问题在这里已经有了答案: What is the maximum number of parameters passed to $in query in MongoDB? (4 个答案) 关闭
我的一个项目的 AndroidManifest.xml 变得越来越大(> 1000 行),因为我必须对某些文件类型使用react并且涵盖所有情况变得越来越复杂。我想知道 list 大小是否有任何限制。
在使用 Sybase、Infomix、DB2 等其他数据库产品多年后使用 MySQL 5.1 Enterprise 时;我遇到了 MySQL 不会做的事情。例如,它只能为 SELECT 查询生成 EX
这个问题在这里已经有了答案: What is the maximum number of parameters passed to $in query in MongoDB? (4 个回答) 关闭5年
通常我们是在{$apache}/conf/httpd.conf中设置Apache的参数,然而我们并没有发现可以设置日志文件大小的配置指令,通过参考http://httpd.apache.org/do
我正在搜索最大的 Android SharedPreferences 键值对,但找不到任何好的答案。其次,我想问一下,如果我有一个键,它的字符串值限制是多少。多少字符可以放入其中。如果我需要频繁更改值
我目前正在试验 SoundCloud API,并注意到我对/tracks 资源的 GET 请求一次从不返回超过 200 个结果。关于这个的几个问题: 这个限制是故意的吗? 有没有办法增加这个限制? 如
我正在与一家名为 Dwolla 的金融技术公司合作,该公司提供了一个 API,用于将银行信息附加到用户并收取/发送 ACH 付款。 他们需要我将我的 TLS 最低版本升级到 1.2(禁用 TLS 1.
我在 PHP 中有一个多维数组,如下所示: $array = Array ( [0] => Array ( [bill] => 1 ) [1] => Array ( [
我在获取下一个查询的第一行时遇到了问题: Select mar.Title MarketTitle, ololo.NUMBER, ololo.Title from Markets mar JOIN(
我是一名优秀的程序员,十分优秀!