How can I use co with express?

2.2k views Asked by At

I'm using express with node and want to use a co/yield patter to wrangle my async callbacks.

The current code looks like this:

web.post('/request/path', function(req, res, next) {
    co(function *() {
        let body = req.body
        let account = yield db.get('account', {key: body.account})
        if (!account) {
            throw new Error('Cannot find account')
        }
        let host = yield db.get('host', {key: body.hostname})
        ....

    }).catch(err => {log.info(err) ; res.send({error: err})})

This is working really well, but I'd like to be able to simplify the first 2 lines:

web.post('/request/path', function(req, res, next) {
    co(function *() {

Is it possible to somehow integrate the co(function *() into the first line? Does express provide support for co() and yielding functions?

2

There are 2 answers

0
Swaraj Giri On

You can use co-express along with promises.

Example,

router.get('/', wrap(function* (req, res, next) {
    var val;

    try {
        val = yield aPromise();
    } catch (e) {
        return next(e);
    }

    res.send(val);
}));
0
Kesarion On

You can simplify the syntax with an arrow function:

web.post('/request/path', (req, res, next) => co(function *() {
        //...
}).catch(err => {log.info(err) ; res.send({error: err})})

I don't see any extra benefit to using another package. When async/await hits the shelves, we may see express get an update.

On a side note, making your own co-express is rather simple:

Consider 'co-express/index.js'

module.exports = generator => (req, res, next) => require('co').wrap(generator)(req, res, next).catch(err => res.status(500).send(err));

And now:

var coe = require('./co-express');
web.post('/request/path', coe(function *(req, res, next) {
    //...
})

This way you've got the latest co package.