Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/swivelgames/thenable-events
Powerful event-based system that introduces thenable objects to enable promise-like event handling.
https://github.com/swivelgames/thenable-events
emitter es2015 es2015-modules es6 events javascript library modules node nodejs promise promises thenable utilities
Last synced: 2 days ago
JSON representation
Powerful event-based system that introduces thenable objects to enable promise-like event handling.
- Host: GitHub
- URL: https://github.com/swivelgames/thenable-events
- Owner: Swivelgames
- License: gpl-3.0
- Created: 2016-11-20T22:55:58.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2022-12-06T20:32:41.000Z (almost 2 years ago)
- Last Synced: 2024-04-14T12:29:17.321Z (7 months ago)
- Topics: emitter, es2015, es2015-modules, es6, events, javascript, library, modules, node, nodejs, promise, promises, thenable, utilities
- Language: JavaScript
- Homepage: https://www.npmjs.com/package/thenable-events
- Size: 146 KB
- Stars: 1
- Watchers: 2
- Forks: 0
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# `thenable-events` v2
Powerful event-based system that introduces thenable objects to enable promise-like event handling#### Version 2 is here!
* Improved compatibility with `thenable` definition in Promises/A+ spec
* Introduction of Namespaced events
* *Contributors: Introduction of proper `mocha` and `chai` tests*## Powerful Features
* Dispatch events
* Handle success and error events using promise-like syntax
* Implements `thenables` compatible with Promises/A+ spec
* Namespaced events work out of the box# Quick Start
Install:
```shell
$ yarn add thenable-events
```Use:
```javascript
import Dispatcher from 'thenable-events';
const EventDispatcher = new Dispatcher();
EventDispatcher.when('eventName').then(val => console.log(val));
EventDispatcher.resolve('eventName', 'Foobar!');
// Console> 'Foobar!'
```## Usage Examples
### Dispatching Events
Traditional event-based systems combine the antiquated `callback` structure in order to handle events:
```javascript
myObservable.on('eventName', () => console.log('Foobar!'));
```While `thenable-events` employs a promise-like structure that is compatible with Promises/A+ implementations:
```javascript
import Dispatcher from 'thenable-events';
const EventDispatcher = new Dispatcher();
EventDispatcher.when('eventName').then(() => console.log('Foobar!'));
```### Handling API Responses
Because of these improvements, we can use the power of chaining in a promise-like structure with event-based syntax where ***the chain is resolved every time an event is fired***.
Here's an example using `axios` for an API call:
```javascript
import axios from 'axios';
import Dispatcher from 'thenable-events';const EventDispatcher = new Dispatcher();
const getData = () =>
axios.get('/svcs/myendpoint').then(
(res) => {
EventDispatcher.resolve('api.myendpoint', res.body);
return res;
},
(err) => {
EventDispatcher.reject('api.myendpoint', err);
throw err;
}
);// ...
EventDispatcher.when('api.myendpoint')
.then(body => JSON.parse(body))
.then(json => console.log({ json }))
.catch(err => console.error(err));
```### Support for Namespaced Event-Names
Support for namespaced event-names works out of the box, enabling handling of a wide-range of events within a single line:
```javascript
const getData = () =>
// ...
EventDispatcher.reject('api.myendpoint', err);
// ...// Catches all rejected events under 'api.myendpoint.*'
EventDispatcher.when('api.*')
.catch(err => {
console.error('Catch-all for All API Errors', err);
});
```## Concepts
With the promises becoming more ubiquitous due to their powerful structure, `thenable-events` employs `thenable` objects (as defined in Promises/A+) with interfaces very similar to Promises.
### Promises/A+ Compatibility
The power of `thenable-events` is the similarity in the way that the `then` interface is implemented. The interface is entirely compatible with traditional Promise/A+ implementations. However, the real power comes from the ability to use promise-like syntax (thenable) within an event-based structure.
So what are the true differences?
It's quite simple, really:
* `thenable-events` resolves each `then` chain every time an event is `resolved` or `rejected`
This is the only limitation with Promises being assimilated in a proper event-based architecture without the need for callbacks.
This issue is solved with `thenable-events`:
#### Old versus New
**Old**
```javascript
myObservable.on('api.myendpoint', (data) => {
let json;
try {
json = JSON.parse(data);
} catch(e) {
console.error(err);
return;
}
console.log({ json });
});
```**New**
```javascript
EventDispatcher.when('api.myendpoint')
.then(body => JSON.parse(body))
.then(json => console.log({ json }))
.catch(err => console.error(err));
```#### Test Suite Results
```
Dispatcher
.when()
✓ should throw an error if there are too many parameters
✓ should be compatible with Promise.all
✓ should be compatible with Promise.race
.then( onFulfilled, onRejected )
✓ should execute `onFulfilled` once if already resolved and once for every subsequent resolve
✓ should execute `onRejected` once if thenable is already rejected and once for every subsequent reject
✓ should accept other promises as return values for `thens`
✓ should return properly chainable `thenables`
✓ should throw an error if there are missing parameters
.catch()
✓ should catch when a thenable is rejected within a then
✓ should only fulfill catches
.once( onFulfilled )
✓ should only fulfill once
✓ should fulfill when thenable is already resolved
✓ should fulfill when a thenable is resolved later
✓ should throw an error if there are missing parameters
.catch()
✓ should catch when a thenable is already rejected
✓ should recover if catch returns a value
✓ should only fulfill catches
✓ should throw an error if there are missing parameters
.resolve
✓ should resolve all 3 thens including those in lower namespaces, excluding those in higher namespaces
✓ should not resolve absolute thens in lower namespaces
.reject
✓ should reject all 3 catchs including those in lower namespaces, excluding those in higher namespaces
✓ should not reject absolute catchs in lower namespaces
```