2022-07-05 22:29:13 +03:00
# stoppable.js
2022-07-08 11:21:07 +03:00
2022-07-05 22:29:13 +03:00
Utility library implementing tooling to make stoppable functions...
2022-07-06 00:23:18 +03:00
2022-07-08 18:58:23 +03:00
This library enables the user to drop out of a function/generator without the
need to thread the result through the call stack. This is in concept similar to
executing `return ..` from a nested loop to terminate and return from a function
but `stoppable.js` allows us to do the same from a nested set of function calls.
This is also similar to _Python_ 's `raise StopIteration` approach to stopping
iteration.
2022-07-06 15:54:03 +03:00
- [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
2022-07-06 00:23:18 +03:00
```shell
$ npm install --save ig-stoppable
```
```javascript
var stoppable = require('ig-stoppable')
```
2022-07-06 15:54:03 +03:00
## 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(..)`
2022-07-09 11:21:20 +03:00
A special object/constructor that can either be returned/thrown _as-is_ or
2022-07-06 15:54:03 +03:00
used to create an _instance_ to be returned thrown.
```bnf
stoppable.STOP
stoppable.STOP()
stoppable.STOP(< value > )
-> < stop-object >
```
2022-07-09 11:21:20 +03:00
This will get intercepted by `stoppable(..)` and appropriately handled, stopping
the function iterator and merging the value into the yields of a generator or
returning it from a function depending on the wrapper type.
2022-07-06 15:54:03 +03:00
`<stop-object>` can contain a value that will get handled by `stoppable(..)` (default: `undefined` ).
## Examples
### Function
2022-07-06 00:23:18 +03:00
```javascript
var func = stoppable(function(){
// ...
throw stoppable.STOP('something')
// ...
})
var value = func() // -> 'something'
```
2022-07-08 18:58:23 +03:00
Dropping out of recursion avoiding threading the result up the chain:
```javascript
// Note that we split the recursive part and the interface part, this is done
// to keep the STOP catching only to the top level and thus avoid threading
// the result back up the recursion...
var _find = function(L, e){
if(L.length == 0){
throw stoppable.STOP(false) }
if(L[0] == e){
throw stoppable.STOP(true) }
// look further down...
_find(L.slice(1), e) }
var find = stoppable(_find)
find([1,2,3,4,5,6,7], 6) // -> true
```
For more examples see [`type.js`' `Array.prototype.smap(..)` and friends ](https://github.com/flynx/types.js#arraysmap--arraysfilter--arraysreduce--arraysforeach ).
2022-07-06 15:54:03 +03:00
### Async function
```javascript
var func = stoppable(async function(){
// ...
throw stoppable.STOP('something')
// ...
})
var value = await func() // -> 'something'
```
### Generator
2022-07-06 00:23:18 +03:00
```javascript
var gen = stoppable(function*(){
// ...
throw stoppable.STOP('something')
// ...
})
var value = [...gen()] // -> ['somthing']
```
2022-07-06 15:54:03 +03:00
### Async generator
2022-07-06 00:23:18 +03:00
```javascript
var agen = stoppable(async function*(){
// ...
throw stoppable.STOP('something')
// ...
})
var value = awat agen() // -> ['something']
2022-07-06 15:54:03 +03:00
```
## License
[BSD 3-Clause License ](./LICENSE )
2023-09-09 16:35:32 +03:00
Copyright (c) 2022-2023, Alex A. Naanou,
2022-07-06 15:54:03 +03:00
All rights reserved.
<!-- vim:set ts=4 sw=4 spell : -->