diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..1f315c0 --- /dev/null +++ b/.babelrc @@ -0,0 +1,11 @@ +{ + "sourceMaps": "inline", + "presets": ["es2015", "stage-1"], + "plugins": [ + "transform-runtime", + ["transform-async-to-module-method", { + "module": "bluebird", + "method": "coroutine" + }] + ] +} diff --git a/index.js b/index.js index 6fddb06..0b59c02 100644 --- a/index.js +++ b/index.js @@ -39,13 +39,19 @@ class Base extends EventEmitter { } _wrapListener(eventName, listener) { - if (is.generatorFunction(listener)) { - assert(eventName !== 'error', '[sdk-base] `error` event should not have a generator listener.'); + if (is.generatorFunction(listener) || is.asyncFunction(listener)) { + assert(eventName !== 'error', '[sdk-base] `error` event should not have a generator/async listener.'); const newListener = (...args) => { - co(function* () { - yield listener(...args); - }).catch(err => { + let promise; + if (is.asyncFunction(listener)) { + promise = listener(...args); + } else { + promise = co(function* () { + yield listener(...args); + }); + } + promise.catch(err => { err.name = 'EventListenerProcessError'; this.emit('error', err); }); @@ -78,7 +84,7 @@ class Base extends EventEmitter { removeListener(eventName, listener) { let target = listener; - if (is.generatorFunction(listener)) { + if (is.generatorFunction(listener) || is.asyncFunction(listener)) { const listeners = this.listeners(eventName); for (const fn of listeners) { if (fn.original === listener) { diff --git a/package.json b/package.json index c04080b..04a68e0 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,13 @@ "egg-ci": "^1.8.0", "eslint": "^4.11.0", "eslint-config-egg": "^5.1.1", - "pedding": "^1.1.0" + "pedding": "^1.1.0", + "babel-plugin-transform-async-to-module-method": "^6.24.0", + "babel-plugin-transform-runtime": "^6.23.0", + "babel-preset-es2015": "^6.24.0", + "babel-preset-stage-1": "^6.24.0", + "babel-register": "^6.26.0", + "bluebird": "^3.3.5" }, "engine": { "node": ">= 6.0.0" diff --git a/test/.setup.js b/test/.setup.js new file mode 100644 index 0000000..c6fe580 --- /dev/null +++ b/test/.setup.js @@ -0,0 +1,9 @@ +'use strict'; + +const ver = process.version; +let major = ver.split('.')[0]; +major = parseInt(major.substr(1), 10); +// below node 8 +if (major < 8) { + require('babel-register'); +} diff --git a/test/index.test.js b/test/index.test.js index 64c62c8..d9c4cab 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -242,6 +242,49 @@ describe('sdk-base', () => { client.emit('event_code', 1, 2); }); + it('should add async listener', done => { + done = pedding(done, 8); + const client = new SomeServiceClient(); + + client.addListener('event_code_async', async function(a, b) { + console.log('event_code_async in addListener'); + assert(a === 1); + assert(b === 2); + done(); + }); + + client.on('event_code_async', async function(a, b) { + console.log('event_code_async in on'); + assert(a === 1); + assert(b === 2); + done(); + }); + + client.once('event_code_async', async function(a, b) { + console.log('event_code_async in once'); + assert(a === 1); + assert(b === 2); + done(); + }); + + client.prependListener('event_code_async', async function(a, b) { + console.log('event_code_async in prependListener'); + assert(a === 1); + assert(b === 2); + done(); + }); + + client.prependOnceListener('event_code_async', async function(a, b) { + console.log('event_code_async in prependOnceListener'); + assert(a === 1); + assert(b === 2); + done(); + }); + + client.emit('event_code_async', 1, 2); + client.emit('event_code_async', 1, 2); + }); + it('should catch generator exception and emit on error event', done => { done = pedding(done, 2); const client = new SomeServiceClient(); @@ -278,6 +321,25 @@ describe('sdk-base', () => { assert(client.listeners('event_code').length === 0); }); + it('should remove async listener', done => { + done = pedding(done, 1); + const client = new SomeServiceClient(); + const handler = async function(data) { + assert(data === 1); + console.log('async listener'); + done(); + }; + client.on('event_code', data => { + assert(data === 1); + console.log('normal listener'); + }); + client.on('event_code_async', handler); + client.emit('event_code', 1); + client.emit('event_code_async', 1); + client.removeListener('event_code_async', handler); + assert(client.listeners('event_code_async').length === 0); + }); + it('should not allow to add generator listener on error event', () => { const client = new SomeServiceClient(); assert.throws(() => {