From d60d4fc3265c59f64b3d8eb2628bbf91290a31ca Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Sun, 17 Jul 2016 00:35:35 +0300 Subject: [PATCH] Add 'throttler' for gen-thread.js --- example.js | 10 ++++++++++ index.js | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/example.js b/example.js index 022011a..84dd93b 100644 --- a/example.js +++ b/example.js @@ -22,3 +22,13 @@ function* test(thread) } gen.run(test, null, function(result) { console.log(result); }); + +function* test_throttle(thread) +{ + yield thread.throttle(5); + console.log('at most 5'); + yield setTimeout(thread, 1000); +} + +for (var i = 0; i < 15; i++) + gen.run(test_throttle); diff --git a/index.js b/index.js index 375006d..e30d648 100644 --- a/index.js +++ b/index.js @@ -1,17 +1,65 @@ module.exports.run = runThread; module.exports.runParallel = runParallel; +var q = []; +var pending = []; + +function finishq() +{ + for (var i = 0; i < q.length; i++) + { + if (q[i]._done) + { + q.splice(i, 1); + i--; + } + } + while (pending.length > 0 && q.length < pending[0][1]) + { + var t = pending.shift(); + q.push(t[0]); + t[0](); + } +} + +var tid = 0; function runThread(main, arg, done) { var thread = function() { // pass parameters as yield result var pass = Array.prototype.slice.call(arguments, 0); - var v = thread.gen.next(pass); + try + { + v = thread.gen.next(pass); + } + catch (e) + { + v = { done: 1 }; + } + if (v.done) + { + thread._done = true; + finishq(); + } if (v.done && done) done(v.value); }; + thread.id = tid++; thread.gen = main(thread, arg); + thread.throttle = function(count) + { + finishq(); + if (q.length < count) + { + q.push(thread); + setTimeout(thread, 1); + } + else + { + pending.push([ thread, count ]); + } + }; thread(); }