我正在处理原始数据并将处理后的URL发送给函数以获取有关该URL的详细信息并将其保存在文本文件中,然后处理1至10 M行的数量较大的CSV文件。有速率限制,因此我需要在每个请求之间等待1分钟。我不能使用正常的“ settimeout”,因为它可能会影响主机内存。所以我尝试了bottleneck npm
const limiter = new Bottleneck({
datastore: "ioredis",
clearDatastore: false,
maxConcurrent: 1,
minTime: 60000,
clientOptions: {
host: config.api.redisHost,
port: config.api.redisPort
}
});
function processRequest(value) {
console.log('value', value, new Date());
}
async function increment(counter) {
console.log(' increment function', new Date());
let result = await limiter.schedule(() => processRequest(counter));
}
//Feed data
for (let i = 0; i < 10; i++) {
increment(i);
}
这里的请求没有等待'minTime',即1分钟。我在做错什么或其他方法吗?我真的很担心内存,这就是为什么我使用“ Redis”。
这将在呼叫processRequest
之间等待一分钟:
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function processFiles() {
// Feed data
let first = true;
for (let i = 0; i < 10; i++) {
if (!first) {
await delay(3600000); // One minute
} else {
first = false;
}
processRequest(i);
}
}
实时示例:
function processRequest(i) {
return new Promise(resolve => {
console.log(`Start request #${i}`);
setTimeout(() => {
console.log(`End request #${i}`);
resolve();
}, 300 + Math.floor(Math.random() * 300)); // Make requests last 300-600ms
});
}
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function processFiles() {
// Feed data
let first = true;
for (let i = 0; i < 10; i++) {
if (!first) {
console.log(`wait 800ms`);
await delay(800); // 800ms
} else {
first = false;
}
await processRequest(i);
}
}
processFiles()
.catch(error => {
// Handle/report error
});
.as-console-wrapper {
max-height: 100% !important;
}
但是,如果速率限制器是基于您的上一个请求开始的时间,而不是结束的时间,则您可能无需等待一整分钟就可以开始另一个请求:
async function processFiles() {
const limit = 3600000; // One minute
// Feed data
let last = Date.now() - limit - 1;
for (let i = 0; i < 10; i++) {
// See how long we have to wait
const wait = Math.max(0, limit - (Date.now() - last));
if (wait > 0) {
await delay(wait);
}
last = Date.now();
processRequest(i);
}
}
实时示例:
function processRequest(i) {
return new Promise(resolve => {
console.log(`Start request #${i}`);
setTimeout(() => {
console.log(`End request #${i}`);
resolve();
}, 300 + Math.floor(Math.random() * 300)); // Make requests last 300-600ms
});
}
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function processFiles() {
const limit = 1200; // 1200ms
// Feed data
let last = Date.now() - limit - 1;
for (let i = 0; i < 10; i++) {
// See how long we have to wait
const wait = Math.max(0, limit - (Date.now() - last));
if (wait > 0) {
console.log(`wait ${wait}ms`);
await delay(wait);
}
last = Date.now();
await processRequest(i);
}
}
processFiles()
.catch(error => {
// Handle/report error
});
.as-console-wrapper {
max-height: 100% !important;
}