Написал я вот такой код:
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);
}
Сколько бы я раз не вызвал wait('timer1', 5) - он должен складывать все вместе в один массив промисов и выдаст результат только когда все закончатся, ну как я предполагал.
Однако наблюдается забавный эффект, а именно когда заканчиваются таймеры - почему-то программа выпадает в process.exit() - заканчивается весь скрипт, хотя запросов еще много впереди.
В коде пишется так
co(function* () {
// ждем 5 сек
if (limit < 0) yield wait('timer1', 5);
});
Прикол не в том чтобы просто в коде подождать для этого можно написать
yield new Promise(resolve => setTimeout(resolve, 5000));
Прикол в том, что некоторые запросы делаются пачками, так называемые batch запросы.
И в пачке далеко не всегда limit запросов! Там может быть например 12 запросов, а лимит сейчас - всего 5. Таким образом нужно сделать 5, а когда таймер резолвнется - сделать остальные 7.
Там получится
var ps = [];
for (let i in requests) {
ps.push(
co(function* () {
if (limit < 0) yield wait('timer1', 5);
});
);
}
return Promise.all(ps);
В данном случае запускается batch таймеров. И закончится они должны все вместе, т.к. один таймер тут не запустишь мне кажется.
Поправьте пожалуйста мой код или направьте в нужном направлении, может быть логика изначально не так.