Search code examples
javascriptexpressecmascript-6async-awaitkoa

What is the purpose of using a JavaScript generator in this example?


I've been reading Koa.js documentation which seems like a really cool little platform I'd like to learn more about as I get my feet wet with async/await and other goodies.

Looks like I'm not quite understanding the role of generators in the new JS. I keep running into examples like these:

// Using .is()
const minify = require('html-minifier');

app.use(function * minifyHTML(next) {
  yield next;

  if (!ctx.response.is('html')) return;

  let body = ctx.body;
  if (!body || body.pipe) return;

  if (Buffer.isBuffer(body)) body = body.toString();
  ctx.body = minify(body);
});


// Streams
app.use(function * (next) {
  ctx.body = someHTTPStream.on('error', ctx.onerror).pipe(PassThrough());
});

What is the purpose of using a generator here? I have to admit I understand how they work but absolutely not see the utility here. Are they necessary for async/await to work?

Why isn't the above example:

app.use(function(next) {
  ctx.body = 'Hello World';
});

Even their Hello World application doesn't do this:

app.use(ctx => {
  ctx.body = 'Hello World';
});

Solution

  • Generators are used by Koa to execute the next middleware in the sequence.

    Koa generators were the method in which Koa handled middleware functions prior to version 2.0.0. Koa 2.x uses async/await instead, which is a new feature to JavaScript.

    The middleware shown in your example would look like this in Koa v2:

    app.use((ctx, next) => {
        await next(); // Execute the next middleware in the sequence
    
        if (!ctx.response.is('html')) return;
    
        let body = ctx.body;
        if (!body || body.pipe) return;
    
        if (Buffer.isBuffer(body)) body = body.toString();
        ctx.body = minify(body);
    });