So, I create a generator and wrap it in an event emitter
const util = require('util')
const EventEmitter = require('events').EventEmitter
// declare a generator that counts forever
function *Generator(n) {
while (true) yield n++
}
function Iterator() {
// initialize a new generator at 0
let c = Generator(0)
this.inc = function() {
// emit an event, bangbang, with next value from generator
this.emit('bangbang', c.next())
}
}
// turn Iterator into an event emitter
util.inherits(Iterator, EventEmitter)
Now I instantiate the event emitter and attach a listener that calls a never ending stream forth from the generator, and away we go
let iterator = new Iterator()
iterator.addListener('bangbang', function(n) {
console.log(n)
iterator.inc()
})
iterator.inc()
This ^ will result in a stack overflow.
But, if I attach iterator.addListener
like so
iterator.addListener('bangbang', function(n) {
setTimeout(function() {
console.log(n)
iterator.inc()
}, 0)
})
it will go on forever.
So then I realized...
function recurse(n) {
console.log(n)
setTimeout(function() {
recurse(n+1)
}, 0)
}
recurse(0)
JavaScript can do things like this ^, your job as a JavaScript programmer is to get return values out of this process. That's what streams, promises, callback, generators are all doing in JavaScript, just trying to get you your return value.