Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

This comment has been minimized.

Copy link

jimmycuadra commented Apr 21, 2011

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

This comment has been minimized.

Copy link
Owner Author

tantalor commented Apr 21, 2011

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
You can’t perform that action at this time.