Koa: when middleware meet setTimeout, ctx.body don't work ?

Created on 18 May 2016  路  13Comments  路  Source: koajs/koa

app.use((ctx, next) => {  
  console.log('1')
  setTimeout(function(){

    console.log('2')
    return next().then(() => {
      // after
      console.log('3')
    })
  }, 1000)  
});


// response
app.use(ctx => {
  console.log('涓氬姟閫昏緫澶勭悊')
  ctx.body = 'i am body'
});

when visit

$ curl http://127.0.0.1:3000
Not Found%                  

Most helpful comment

You should return Promise in middleware

app.use((ctx, next) => {  
  console.log('1');
  return new Promise(resolve => {
    setTimeout(resolve, 1000);
  })
  .then(() => {
      console.log('2');
      return next().then(() => {
        // after
        console.log('3');
      });
  });
});

// response
app.use(ctx => {
  console.log('涓氬姟閫昏緫澶勭悊');
  ctx.body = 'i am body';
});

Much better with async await:

app.use(async (ctx, next) => {  
  console.log('1');
  await new Promise(resolve => {
    setTimeout(resolve, 1000);
  });
  console.log('2');
  await next();
  // after
  console.log('3');
});

// response
app.use(ctx => {
  console.log('涓氬姟閫昏緫澶勭悊');
  ctx.body = 'i am body';
});

All 13 comments

You should return Promise in middleware

app.use((ctx, next) => {  
  console.log('1');
  return new Promise(resolve => {
    setTimeout(resolve, 1000);
  })
  .then(() => {
      console.log('2');
      return next().then(() => {
        // after
        console.log('3');
      });
  });
});

// response
app.use(ctx => {
  console.log('涓氬姟閫昏緫澶勭悊');
  ctx.body = 'i am body';
});

Much better with async await:

app.use(async (ctx, next) => {  
  console.log('1');
  await new Promise(resolve => {
    setTimeout(resolve, 1000);
  });
  console.log('2');
  await next();
  // after
  console.log('3');
});

// response
app.use(ctx => {
  console.log('涓氬姟閫昏緫澶勭悊');
  ctx.body = 'i am body';
});

@chentsulin

thanks

async/await performance is lower than generator, see https://github.com/17koa/koa-benchmark

and another way is

app.use((ctx, next) => {  
  console.log('1')
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve();

      return next().then(() => {

        // after
        console.log('3')
      })

    }, 100);
  });
});

koa team call this modern middleware, maybe it is recommendation util node support async/await

(ctx, next) => { 
}

It's unlikely we will need 50-100 middlewares for every services. In my case, It's works great.

please use async/await. or just write all in promise.

@i5ting Maybe you need to read koa request handle flow deeply again.
I don't think you real know how koa work.

app.use(function *(ctx, next) {
  yield new Promise(function (resolve) {
    setTimeout(function () {
      resolve()
    }, 100)
  })

  yield next;

  console.log('3')
})

and you can also use ko-sleep http://npm.taobao.org/package/ko-sleep

Also a delay package do something similar to ko-sleep https://www.npmjs.com/package/delay

Also a promise.delay package do something similar to delay & ko-sleep
https://github.com/magicdawn/promise.delay
馃槀 馃槀 馃槀

and same to require('bluebird').delay

why not get a benchmark to see who sleeps best ? 馃槀

_random your mum joke_

Bluebird: promise.then().timeout(1024).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

TheRav3n picture TheRav3n  路  3Comments

ElegantScripting picture ElegantScripting  路  5Comments

dounine picture dounine  路  4Comments

sibelius picture sibelius  路  3Comments

tvq picture tvq  路  4Comments