add experimental async function support

This commit is contained in:
Jonathan Ong 2014-12-17 18:06:45 -08:00
parent 0e02798a8b
commit c5545cd918
6 changed files with 47 additions and 7 deletions

View file

@ -15,7 +15,8 @@ endif
TESTS = test/application \ TESTS = test/application \
test/context/* \ test/context/* \
test/request/* \ test/request/* \
test/response/* test/response/* \
test/experimental/index.js
test: test:
@NODE_ENV=test $(BIN) $(FLAGS) \ @NODE_ENV=test $(BIN) $(FLAGS) \

View file

@ -4,6 +4,7 @@
var debug = require('debug')('koa:application'); var debug = require('debug')('koa:application');
var Emitter = require('events').EventEmitter; var Emitter = require('events').EventEmitter;
var compose_es7 = require('composition');
var onFinished = require('on-finished'); var onFinished = require('on-finished');
var response = require('./response'); var response = require('./response');
var compose = require('koa-compose'); var compose = require('koa-compose');
@ -94,7 +95,10 @@ app.toJSON = function(){
*/ */
app.use = function(fn){ app.use = function(fn){
assert(fn && 'GeneratorFunction' == fn.constructor.name, 'app.use() requires a generator function'); if (!this.experimental) {
// es7 async functions are allowed
assert(fn && 'GeneratorFunction' == fn.constructor.name, 'app.use() requires a generator function');
}
debug('use %s', fn._name || fn.name || '-'); debug('use %s', fn._name || fn.name || '-');
this.middleware.push(fn); this.middleware.push(fn);
return this; return this;
@ -110,8 +114,9 @@ app.use = function(fn){
app.callback = function(){ app.callback = function(){
var mw = [respond].concat(this.middleware); var mw = [respond].concat(this.middleware);
var gen = compose(mw); var fn = this.experimental
var fn = co.wrap(gen); ? compose_es7(mw)
: co.wrap(compose(mw));
var self = this; var self = this;
if (!this.listeners('error').length) this.on('error', this.onerror); if (!this.listeners('error').length) this.on('error', this.onerror);

View file

@ -19,7 +19,8 @@
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"accepts": "^1.2.2", "accepts": "^1.2.2",
"co": "^4.1.0", "co": "^4.4.0",
"composition": "^2.1.1",
"content-disposition": "~0.5.0", "content-disposition": "~0.5.0",
"content-type": "^1.0.0", "content-type": "^1.0.0",
"cookies": "~0.5.0", "cookies": "~0.5.0",
@ -42,6 +43,7 @@
"vary": "^1.0.0" "vary": "^1.0.0"
}, },
"devDependencies": { "devDependencies": {
"6to5": "^3.6.5",
"istanbul-harmony": "~0.3.0", "istanbul-harmony": "~0.3.0",
"make-lint": "^1.0.1", "make-lint": "^1.0.1",
"mocha": "^2.0.1", "mocha": "^2.0.1",

View file

@ -104,16 +104,21 @@ describe('app.use(fn)', function(){
}); });
}) })
it('should error when a non-generator function is passed', function(done){ it('should error when a non-generator function is passed', function(){
var app = koa(); var app = koa();
try { try {
app.use(function(){}); app.use(function(){});
} catch (err) { } catch (err) {
err.message.should.equal('app.use() requires a generator function'); err.message.should.equal('app.use() requires a generator function');
done();
} }
}) })
it('should not error when a non-generator function is passed when .experimental=true', function(){
var app = koa();
app.experimental = true;
app.use(function(){});
})
}) })
describe('app.onerror(err)', function(){ describe('app.onerror(err)', function(){

View file

@ -0,0 +1,23 @@
/**
* Separate file primarily because we use `require('6to5/register')`.
*/
var request = require('supertest');
var koa = require('../..');
describe('.experimental=true', function () {
it('should support async functions', function (done) {
var app = koa();
app.experimental = true;
app.use(async function (next) {
var string = await Promise.resolve('asdf');
this.body = string;
});
request(app.callback())
.get('/')
.expect('asdf')
.expect(200, done);
})
})

View file

@ -0,0 +1,4 @@
require('6to5/register')({
optional: ['asyncToGenerator']
});
require('./async');