On Github hoeck / dresdenjs-generators-part-two
function* range (start, end) {
    while (start < end) {
        yield start++;
    }
}
const gen = range(5, 7);
gen.next() // => {value: 5, done: false}
gen.next() // => {value: 6, done: false}
gen.next() // => {done: true}
function* defines a generator function yield produces the generators values calling it creates a generator instance next() delivers the generators values next() delivers the generators values until there are no more values
Example: web application handler, synchronous version
function handler (sessionid, response):
    const session = loadSessionSync(sessionid);
    const user = loadUserSync(session.userId);
    response.send(`Hello ${user.name}`);
load a session from the db and wait load a user from the db and wait create the response
function handler (sessionid, response) {
    loadSession(sessionid, function (err, session) {
        if (err) response.status(500).send();
        loadUser(session.userId, function (err, user) {
            if (err) response.status(500).send();
            response.send(`hello ${user.name}`);
        })
    });
};
load a session from the db, when done, invoke a callback load a user from the db, when done, invoke a callback create and send the response deal with errors in each callback
loadUser(userId, function (err, user) {
    response.send(`hello ${user.name}`);
}
function handler (sessionid, response) {
    loadSession(sessionid).then(function (session) {
        return loadUser(session.userId);
    }).then(function (user) {
        response.send(`hello ${user.name}`);
    }).catch(function (err) {
        response.status(500).send();
    });
};
load a session from the db, when done, return a promise load a user from the db, when done, return a promoise create and send the response error handling for the promise chain
loadSession(sessionid).then(function (session) {
    return loadUser(session.userId);
})
function * handler (sessionid, response) {
    const session = yield loadSession(sessionId);
    const user = yield loadUser(session.userId);
    response.send(`hello ${user.name}`);
}
load a session from the db, when done, keep it in session load a user from the db, when done, keep it in user create and send the response errors are thrown and can be catched (e.g. by the framework)
// blocking
function handler (sessionid, response) {
    const session = loadSessionSync(sessionid);
    const user = loadUserSync(session.userId);
    response.send(`Hello ${user.name}`);
}
// non-blocking
function * handler (sessionid, response) {
    const session = yield loadSession(sessionId);
    const user = yield loadUser(session.userId);
    response.send(`hello ${user.name}`);
}
the same, except yield the same, except yield
with generators
to actually write non-blocking generator code
downloading files
import co from co;
import fs from 'mz/fs';
import request from 'request-promise';
const loadFiles = co.wrap(function* (targets) {
    for (target of targets) {
        const data = yield request.get(target.url);
        yield fs.writeFile(target.name, data);
    }
});
loadFiles(files).then(() => {
    console.log('done');
}).catch((err) => {
    console.log(err.stack);
});
co: transforms a generator into a promise mz/fs: nodejs filesystem module using promises request-promise: http client using promises
the generator co.wrap turns a generator into a Promise loop through all targets request.get(target.url) fetches an url and returns a Promise yield takes the promise and passes execution to co const data: once the promise is resolved, co consumes the generator fs.writeFile writes data to a file, when done, the loop continues
calling loadFiles returns a promise
ES7 async & await
function * handler (sessionid, response) {
    const session = yield loadSession(sessionId);
    const user = yield loadUser(session.userId);
    response.send(`hello ${user.name}`);
}
const promise = co.wrap(handler)(sessionid, response);
// turns into
async function handler () {
    const session = await loadSession(sessionId);
    const user = await loadUser(session.userId);
    response.send(`hello ${user.name}`);
}
const promise = handler(sessionid, response);
function * async function yield await and you don't need co