Skip to content

Instantly share code, notes, and snippets.

@tantalor
Created April 20, 2011 23:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tantalor/933355 to your computer and use it in GitHub Desktop.
Save tantalor/933355 to your computer and use it in GitHub Desktop.
buffering asynchronous iterator pattern
// produce: accepts a cb which is called with an array of items
// initial: initial array of results to return
// returns a function which accepts a cb which is called with one item
// each time it is called
function generator(produce, initial) {
var items;
var waiting = [];
var next = function (cb) {
if (items && items.length) {
cb(items.shift());
if (items.length == 0) consume()
} else {
waiting.push(cb);
}
}
function consume () {
produce(function (new_items) {
items = new_items;
while (waiting.length && items && items.length) {
next(waiting.pop())
}
});
}
if (initial && initial.length) {
items = initial;
} else {
consume();
}
return next;
}
// example
var sys = require('sys');
var print = (function (s) {sys.print(s+"\n")})
var my_producer = (function () {
var i = 0;
return function (cb) {
setTimeout(function () {
cb([++i, ++i]);
}, 1000);
}
})();
var my_generator = generator(my_producer);
my_generator(print);
my_generator(print);
my_generator(print);
@jimmycuadra
Copy link

Array.prototype.push(results, new_results); pushes results and new_results onto Array.prototype, which I don't think is the intention here. results = results.concat(new_results); is probably the best approach.

@tantalor
Copy link
Author

Yep I meant Array.prototype.push.apply(results, new_results). There was a bunch of stuff wrong so I spruced it up and added an example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment