feat(emit-async): handle async listeners (#3416)

Extracted from xo-server.
This commit is contained in:
Julien Fontanet 2018-09-17 10:42:22 +02:00 committed by GitHub
parent b4e4d32255
commit 8689cff26b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 174 additions and 27 deletions

View File

@ -0,0 +1,3 @@
module.exports = require('../../@xen-orchestra/babel-config')(
require('./package.json')
)

View File

@ -0,0 +1,24 @@
/benchmark/
/benchmarks/
*.bench.js
*.bench.js.map
/examples/
example.js
example.js.map
*.example.js
*.example.js.map
/fixture/
/fixtures/
*.fixture.js
*.fixture.js.map
*.fixtures.js
*.fixtures.js.map
/test/
/tests/
*.spec.js
*.spec.js.map
__snapshots__/

View File

@ -0,0 +1,71 @@
# @xen-orchestra/emit-async [![Build Status](https://travis-ci.org/${pkg.shortGitHubPath}.png?branch=master)](https://travis-ci.org/${pkg.shortGitHubPath})
> ${pkg.description}
## Install
Installation of the [npm package](https://npmjs.org/package/@xen-orchestra/emit-async):
```
> npm install --save @xen-orchestra/emit-async
```
## Usage
```js
import EE from 'events'
import emitAsync from '@xen-orchestra/emit-async'
const ee = new EE()
ee.emitAsync = emitAsync
ee.on('start', async function () {
// whatever
})
// similar to EventEmmiter#emit() but returns a promise which resolves when all
// listeners have resolved
await ee.emitAsync('start')
// by default, it will rejects as soon as one listener reject, you can customise
// error handling though:
await ee.emitAsync({
onError (error) {
console.warn(error)
}
}, 'start')
```
## Development
```
# Install dependencies
> yarn
# Run the tests
> yarn test
# Continuously compile
> yarn dev
# Continuously run the tests
> yarn dev-test
# Build for production (automatically called by npm install)
> yarn build
```
## Contributions
Contributions are *very* welcomed, either on the documentation or on
the code.
You may:
- report any [issue](${pkg.bugs})
you've encountered;
- fork and create a pull request.
## License
${pkg.license} © [${pkg.author.name}](${pkg.author.url})

View File

@ -0,0 +1,47 @@
{
"private": true,
"name": "@xen-orchestra/emit-async",
"version": "0.0.0",
"license": "ISC",
"description": "",
"keywords": [],
"homepage": "https://github.com/vatesfr/xen-orchestra/tree/master/@xen-orchestra/emit-async",
"bugs": "https://github.com/vatesfr/xen-orchestra/issues",
"repository": {
"type": "git",
"url": "https://github.com/vatesfr/xen-orchestra.git"
},
"author": {
"name": "Julien Fontanet",
"email": "julien.fontanet@vates.fr"
},
"preferGlobal": false,
"main": "dist/",
"bin": {},
"files": [
"dist/"
],
"browserslist": [
">2%"
],
"engines": {
"node": ">=6"
},
"dependencies": {},
"devDependencies": {
"@babel/cli": "7.0.0",
"@babel/core": "7.0.0",
"@babel/preset-env": "7.0.0",
"babel-plugin-lodash": "^3.3.2",
"cross-env": "^5.1.3",
"rimraf": "^2.6.2"
},
"scripts": {
"build": "cross-env NODE_ENV=production babel --source-maps --out-dir=dist/ src/",
"clean": "rimraf dist/",
"dev": "cross-env NODE_ENV=development babel --watch --source-maps --out-dir=dist/ src/",
"prebuild": "yarn run clean",
"predev": "yarn run prebuild",
"prepublishOnly": "yarn run build"
}
}

View File

@ -0,0 +1,26 @@
export default function emitAsync (event) {
let opts
let i = 1
// an option object has been passed as first param
if (typeof event !== 'string') {
opts = event
event = arguments[i++]
}
const n = arguments.length - i
const args = new Array(n)
for (let j = 0; j < n; ++j) {
args[j] = arguments[j + i]
}
const onError = opts != null && opts.onError
return Promise.all(
this.listeners(event).map(listener =>
new Promise(resolve => {
resolve(listener.apply(this, args))
}).catch(onError)
)
)
}

View File

@ -19,6 +19,7 @@
### Released packages
- @xen-orchestra/emit-async v0.0.0
- xo-server v5.27.0
- xo-web v5.27.0

View File

@ -33,6 +33,7 @@
"dependencies": {
"@babel/polyfill": "7.0.0",
"@xen-orchestra/cron": "^1.0.3",
"@xen-orchestra/emit-async": "^0.0.0",
"@xen-orchestra/fs": "^0.3.0",
"ajv": "^6.1.1",
"app-conf": "^0.5.0",

View File

@ -1,34 +1,8 @@
import createLogger from 'debug'
import emitAsync from '@xen-orchestra/emit-async'
const debug = createLogger('xo:hooks')
function emitAsync (event) {
let opts
let i = 1
// an option object has been passed as first param
if (typeof event !== 'string') {
opts = event
event = arguments[i++]
}
const n = arguments.length - i
const args = new Array(n)
for (let j = 0; j < n; ++j) {
args[j] = arguments[j + i]
}
const onError = opts != null && opts.onError
return Promise.all(
this.listeners(event).map(listener =>
new Promise(resolve => {
resolve(listener.apply(this, args))
}).catch(onError)
)
)
}
const makeSingletonHook = (hook, postEvent) => {
let promise
return function () {