added async function support + docs...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2022-07-06 15:54:03 +03:00
parent 21a343b5d2
commit 7d9b494305
3 changed files with 118 additions and 9 deletions

View File

@ -1,6 +1,23 @@
# stoppable.js
Utility library implementing tooling to make stoppable functions...
- [stoppable.js](#stoppablejs)
- [Install / import](#install--import)
- [Components](#components)
- [`stoppable(..)`](#stoppable)
- [`stoppable.STOP / stoppable.STOP(..)`](#stoppablestop--stoppablestop)
- [Examples](#examples)
- [Function](#function)
- [Async function](#async-function)
- [Generator](#generator)
- [Async generator](#async-generator)
- [License](#license)
## Install / import
```shell
$ npm install --save ig-stoppable
```
@ -10,6 +27,52 @@ var stoppable = require('ig-stoppable')
```
## Components
### `stoppable(..)`
Create a wrapper for the input function/generator.
```bnf
stoppable(<function>)
-> <function>
stoppable(<async-function>)
-> <async-function>
stoppable(<generator>)
-> <generator>
stoppable(<async-generator>)
-> <async-generator>
```
### `stoppable.STOP / stoppable.STOP(..)`
A special object/constructor that can be either returned/thrown _as-is_ or
used to create an _instance_ to be returned thrown.
```bnf
stoppable.STOP
stoppable.STOP()
stoppable.STOP(<value>)
-> <stop-object>
```
This will get intercepted by `stoppable(..)` and appropriately handled merging
it into the return/yield value and stopping the function/iterator.
`<stop-object>` can contain a value that will get handled by `stoppable(..)` (default: `undefined`).
## Examples
### Function
```javascript
var func = stoppable(function(){
// ...
@ -22,6 +85,23 @@ var func = stoppable(function(){
var value = func() // -> 'something'
```
### Async function
```javascript
var func = stoppable(async function(){
// ...
throw stoppable.STOP('something')
// ...
})
var value = await func() // -> 'something'
```
### Generator
```javascript
var gen = stoppable(function*(){
// ...
@ -34,6 +114,9 @@ var gen = stoppable(function*(){
var value = [...gen()] // -> ['somthing']
```
### Async generator
```javascript
var agen = stoppable(async function*(){
// ...
@ -44,4 +127,15 @@ var agen = stoppable(async function*(){
})
var value = awat agen() // -> ['something']
```
```
## License
[BSD 3-Clause License](./LICENSE)
Copyright (c) 2022-, Alex A. Naanou,
All rights reserved.
<!-- vim:set ts=4 sw=4 spell : -->

View File

@ -1,6 +1,6 @@
{
"name": "ig-stoppable",
"version": "2.0.0",
"version": "2.0.1",
"description": "Utility library implementing tooling to make stoppable functions...",
"main": "stoppable.js",
"scripts": {

View File

@ -18,6 +18,9 @@
//---------------------------------------------------------------------
// helpers...
var AsyncFunction =
(async function(){}).constructor
var Generator =
(function*(){}).constructor
@ -66,10 +69,9 @@ var AsyncGenerator =
module =
function(func){
return Object.assign(
// NOTE: the below implementations are almost the same, the main
// differences being the respective generator/async mechanics...
func instanceof Generator ?
// NOTE: the only difference between Generator/AsyncGenerator
// versions of this is the async keyword -- keep them
// in sync...
function*(){
try{
for(var res of func.call(this, ...arguments)){
@ -87,12 +89,9 @@ function(func){
return }
throw err } }
: func instanceof AsyncGenerator ?
// NOTE: the only difference between Generator/AsyncGenerator
// versions of this is the async keyword -- keep them
// in sync...
async function*(){
try{
for(var res of func.call(this, ...arguments)){
for await(var res of func.call(this, ...arguments)){
if(res === module.STOP){
return }
if(res instanceof module.STOP){
@ -106,6 +105,22 @@ function(func){
yield err.value
return }
throw err } }
: func instanceof AsyncFunction ?
async function(){
try{
var res = await func.call(this, ...arguments)
// NOTE: this is here for uniformity...
if(res === module.STOP){
return }
if(res instanceof module.STOP){
return res.value }
return res
} catch(err){
if(err === module.STOP){
return
} else if(err instanceof module.STOP){
return err.value }
throw err } }
: function(){
try{
var res = func.call(this, ...arguments)