Support chaining generators

master
Vitaliy Filippov 2016-07-19 13:38:35 +03:00
parent 21b45667f1
commit dce1046222
2 changed files with 31 additions and 3 deletions

View File

@ -28,6 +28,14 @@ function* test_throttle(thread)
yield thread.throttle(5); yield thread.throttle(5);
console.log('at most 5'); console.log('at most 5');
yield setTimeout(thread, 1000); yield setTimeout(thread, 1000);
console.log('continue in another generator');
yield other_gen(thread);
}
function* other_gen(thread)
{
yield setTimeout(thread, 1000);
console.log('finished in another generator');
} }
for (var i = 0; i < 15; i++) for (var i = 0; i < 15; i++)

View File

@ -32,24 +32,43 @@ function runThread(main, arg, done)
var v; var v;
try try
{ {
v = thread.gen.next(pass); v = thread.gens[0].next(pass);
} }
catch (e) catch (e)
{ {
v = { done: 1, error: e }; v = { done: 1, error: e };
} }
if (v.done) if (v.done)
{
// generator finished
thread.gens.shift();
if (thread.gens.length)
{
// return to previous generator
thread(v.value);
return;
}
}
if (typeof v.value == 'object' &&
v.value.constructor.constructor == thread.gens[0].constructor.constructor)
{
// another generator instance returned - add it to stack and call
thread.gens.unshift(v.value);
thread();
return;
}
if (!thread.gens.length)
{ {
thread._done = true; thread._done = true;
process.nextTick(finishq); process.nextTick(finishq);
} }
if (v.error) if (v.error)
throw v.error; throw v.error;
if (v.done && done) if (!thread.gens.length && done)
done(v.value); done(v.value);
}; };
thread.id = tid++; thread.id = tid++;
thread.gen = main(thread, arg); thread.gens = [ main(thread, arg) ];
thread.throttle = function(count) thread.throttle = function(count)
{ {
finishq(); finishq();
@ -82,6 +101,7 @@ function runThread(main, arg, done)
return fn; return fn;
}; };
thread(); thread();
return thread;
} }
function runParallel(threads, done) function runParallel(threads, done)