Search code examples
node.jskoanodejs-stream

How can I generate a slow response using koa?


When running koa I get the following warning:

deprecated Support for generators will be removed in v3

What my code does is to create a slow response. E.g. write to response every 1 second, for 30 seconds.

(new Koa()).use(function *(){
  const tr = through();
  setInterval(() => tr.write('blabla\n'), 1000);
  setTimeout(tr.end, 30000);
  this.type = 'text';
  this.body = tr;
}).listen(3003, () => console.log('Listen 3003: slow response'));
curl http://localhost:3003

HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Date: Wed, 27 Feb 2019 21:17:06 GMT
Connection: keep-alive
Transfer-Encoding: chunked

blabla
blabla
blabla
blabla
...

Note: Messages are printed one by one.

How can I achieve the above using the v3 way?


Solution

  • To be clear, v3 is not out, that's just a deprecation warning that Koa is moving away from generator functions. You are not making use of yield so it's pretty easy to convert it:

    const Koa = require('koa');
    const through = require('through');
    
    (new Koa()).use((ctx) => {
      const tr = through();
      setInterval(() => tr.write('blabla\n'), 1000);
      setTimeout(tr.end, 30000);
      ctx.type = 'text';
      ctx.body = tr;
    }).listen(3003, () => console.log('Listen 3003: slow response'));
    
    1. Replace the generator function with a regular function or arrow function, which has an argument ctx

    2. Replace this with ctx

    Edit: Also, I believe there's a bug with this code. You're creating a new interval with every request but never clearing them. I think this would be considered a memory leak.

    You should probably do something more like this:

    const Koa = require('koa');
    const through = require('through');
    
    (new Koa()).use((ctx) => {
      const tr = through();
      let intervalId = setInterval(() => tr.write('blabla\n'), 1000);
      setTimeout(end(intervalId, tr), 30000);
      ctx.type = 'text';
      ctx.body = tr;
    }).listen(3003, () => console.log('Listen 3003: slow response'));
    
    function end(intervalId, tr) {
      return () => {
        clearInterval(intervalId);
        tr.end();
      }
    }