Answer the question
In order to leave comments, you need to log in
How to write a synchronous wait in JS?
I wrote this code:
var show_timer = false;
var waits = {};
var default_limit_burst = 12;
var default_limit_minute = 200;
var limit_burst = 12;
var limit_minute = 200;
function wait(name, timeout) {
let obj = {};
// init
waits[name] = waits[name] || {};
waits[name].irv = waits[name].irv || [];
waits[name].ps = waits[name].ps || [];
// create interval
obj.promise = new Promise((resolve, reject) => {
obj.left = timeout;
obj.interval = setInterval(() => {
obj.left--;
if (show_timer) console.log('Timer `' + name + '`. Left: ' + obj.left);
if (obj.left <= 0) {
clearInterval(obj.interval);
resolve([null, 'OK']);
}
}, 1200);
}).catch(frpd);
// get old keys
var keys = array_keys(waits[name].ps) || [];
// save new items
waits[name].irv.push(obj.interval);
waits[name].ps.push(obj.promise);
// try to resolve all old promises/intervals except current
try {
keys.forEach(v => {
clearInterval(waits[name].irv[v]);
Promise.resolve(waits[name].ps[v]);
});
} catch (e) {
frpd(e);
}
// return batch promise
return Promise.all(waits[name].ps);
}
co(function* () {
// ждем 5 сек
if (limit < 0) yield wait('timer1', 5);
});
yield new Promise(resolve => setTimeout(resolve, 5000));
var ps = [];
for (let i in requests) {
ps.push(
co(function* () {
if (limit < 0) yield wait('timer1', 5);
});
);
}
return Promise.all(ps);
Answer the question
In order to leave comments, you need to log in
So far, it has worked like this:
instead of starting a timer for each request in a pack, I wrote something like this:
co(function* () {
var limit_burst = default_limit_burst;
var limit_minute = default_limit_minute;
var limit_day = default_limit_day;
// getting records from somewhere
var records = get_the_records();
records = yield co(function* () {
var records_done = [];
while (records.length) {
let limit = Math.min(limit_burst, limit_minute, limit_day);
let batch = records.splice(0, limit);
// update limits
limit_burst -= batch.length;
limit_minute -= batch.length;
limit_day -= batch.length;
for (let i in batch) {
// ... request
}
// refresh limits from response headers if available
yield Promise.all(ps).then(results => {
var current_limit_burst = default_limit_burst;
var current_limit_minute = default_limit_minute;
var current_limit_day = default_limit_day;
// save results
records_done = results.map(r => {
if (r[0] !== null) return console.error(r[1]) || null;
current_limit_burst = Math.min(current_limit_burst, r[2][0]);
current_limit_minute = Math.min(current_limit_minute, r[2][1]);
current_limit_day = Math.min(current_limit_day, r[2][2]);
return r[1];
}).filter(r => r!==null);
limit_burst = current_limit_burst;
limit_minute = current_limit_minute;
limit_day = current_limit_day;
});
if (limit_burst <= 0) yield new Promise(r => setTimeout(r, 5000));
if (limit_minute <= 0) yield new Promise(r => setTimeout(r, 60000));
if (limit_day <= 0) yield new Promise(r => setTimeout(r, 86400000));
}
return records_done;
});
});
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question