cleanup and docs...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2022-06-13 22:48:07 +03:00
parent bc60d1b31f
commit 97b8fd6dd5
2 changed files with 108 additions and 7 deletions

View File

@ -401,8 +401,27 @@ object.Constructor('IterablePromise', Promise, {
lastIndexOf: promiseProxy('lastIndexOf'),
includes: promiseProxy('includes'),
//
// .find(<func>)
// .find(<func>, 'value')
// -> <promise>(<value>)
//
// .find(<func>, 'result')
// -> <promise>(<result>)
//
// .find(<func>, 'bool')
// -> <promise>(<bool>)
//
// NOTE: this is slightly different to Array's .find(..) in that it
// accepts the result value enabling returning both the value
// itself ('value', default), the test function's result
// ('result') or true/false ('bool') -- this is added to be
// able to distinguish between the undefined as a stored value
// and undefined as a "nothing found" result.
// NOTE: I do not get how essentially identical methods .some(..)
// and .find(..) got added to the Array...
// and .find(..) got added to JS's Array...
// the only benefit is that .some(..) handles undefined values
// stored in the array better...
// NOTE: this will return the result as soon as it's available but
// it will not stop the created but unresolved at the time
// promises from executing, this is both good and bad:
@ -410,7 +429,7 @@ object.Constructor('IterablePromise', Promise, {
// to resolve...
// - if no clients are available this can lead to wasted
// CPU time...
find: async function(func){
find: async function(func, result='value'){
var that = this
// NOTE: not using pure await here as this is simpler to actually
// control the moment the resulting promise resolves without
@ -418,9 +437,15 @@ object.Constructor('IterablePromise', Promise, {
return new Promise(function(resolve, reject){
var resolved = false
that.map(function(elem){
if(func(elem)){
var res = func(elem)
if(res){
resolved = true
resolve(elem)
resolve(
result == 'bool' ?
true
: result == 'result' ?
res
: elem)
// XXX EXPEREMENTAL: STOP...
// NOTE: we do not need to throw STOP here
// but it can prevent some overhead...
@ -428,11 +453,15 @@ object.Constructor('IterablePromise', Promise, {
throw that.constructor.STOP } } })
.then(function(){
resolved
|| resolve(undefined) }) }) },
|| resolve(
result == 'bool' ?
false
: undefined) }) }) },
findIndex: promiseProxy('findIndex'),
// NOTE: this is just a special-case of .find(..)
some: async function(func){
return !!(await this.find(func)) },
return this.find(func, 'bool') },
every: promiseProxy('every'),

View File

@ -78,10 +78,13 @@ Library of JavaScript type extensions, types and utilities.
- [`<promise-iter>.concat(..)`](#promise-iterconcat)
- [`<promise-iter>.push(..)` / `<promise-iter>.unshift(..)`](#promise-iterpush--promise-iterunshift)
- [`<promise-iter>.at(..)` / `<promise-iter>.first()` / `<promise-iter>.last()`](#promise-iterat--promise-iterfirst--promise-iterlast)
- [`<promise-iter>.some(..)` / `<promise-iter>.find(..)`](#promise-itersome--promise-iterfind)
- [Array proxy methods returning `<promise-iter>`](#array-proxy-methods-returning-promise-iter)
- [Array proxy methods returning a `<promise>`](#array-proxy-methods-returning-a-promise)
- [`<promise-iter>.then(..)` / `<promise-iter>.catch(..)` / `<promise-iter>.finally(..)`](#promise-iterthen--promise-itercatch--promise-iterfinally)
- [`promise.IterablePromise.STOP` / `promise.IterablePromise.STOP(..)`](#promiseiterablepromisestop--promiseiterablepromisestop)
- [Advanced handler](#advanced-handler)
- [Stopping the iteration](#stopping-the-iteration)
- [Promise proxies](#promise-proxies)
- [`<promise>.as(..)`](#promiseas)
- [`<promise-proxy>.<method>(..)`](#promise-proxymethod)
@ -1674,6 +1677,46 @@ parent `<promise-iter>`.
XXX
#### `<promise-iter>.some(..)` / `<promise-iter>.find(..)`
```bnf
<promise-iter>.some(<func>)
-> <promise>
<promise-iter>.find(<func>)
-> <promise>
```
The main difference between `.some(..)` and `.find(..)` is in that the `<promise>`
returned from the former will resolve to either `true` or `false`, and in the later
to the found value or `undefined`.
`.find(..)` supports an additional argument that controls what returned `<promise>`
is resolved to...
```bnf
<promise-iter>.find(<func>)
<promise-iter>.find(<func>, 'value')
-> <promise>
<promise-iter>.find(<func>, 'bool')
-> <promise>
<promise-iter>.find(<func>, 'result')
-> <promise>
```
- `value` (default)
resolve to the stored value if found and `undefined` otherwise.
- `bool`
resolve to `true` if the value is found and `false` otherwise, this is how
`.some(..)` is impelemnted.
- `result`
resolve to the return value of the test `<func>`.
These are similar to [`<array>.some(..)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some)
and [`<array>.find(..)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find)
see them for more info.
#### Array proxy methods returning `<promise-iter>`
@ -1697,7 +1740,8 @@ XXX links...
- `<promise-iter>.indexOf(..)`
- `<promise-iter>.includes(..)`
- `<promise-iter>.every(..)` / `<promise-iter>.some(..)`
- `<promise-iter>.every(..)`
- `<promise-iter>.findIndex(..)`
These methods are proxies to the appropriate array methods.
@ -1727,6 +1771,16 @@ this adds the ability to pass no arguments
This will return a generic promise wrapper passing through the results as-is. This
can be useful to hide the extended promise API from further code.
#### `promise.IterablePromise.STOP` / `promise.IterablePromise.STOP(..)`
A special object that when thrown from a function/promise handler will stop
further iteration.
This is `undefined` until the `ig-types/Array` module is loaded.
For more info see: [Stopping the iteration](#stopping-the-iteration) below, and
[the 'Array' STOP section](#arraystop--arraystop)
#### Advanced handler
@ -1778,6 +1832,24 @@ var p = Promise.iter(
console.log(lst) }) // -> [2, 2, 4, 4, [5, 6]]
```
#### Stopping the iteration
Like the [`Array`](#arraystop--arraystop) module, this support throwing `STOP` to
stop iteration. As we uses [`.smap(..)`](#arraysmap--arraysfilter--arraysreduce--arraysforeach)
stopping support is supported if `ig-types/Array` module is loaded.
```javascript
require('ig-types/Array')
```
This is also different semantically, as promise iteration can happen out of order,
stopping affects the order of processing and not order of the input array with one exception: promises already created can not be stopped in `JavaScript`.
Any handler function passed to a `<promise-iter>` method can `throw` a STOP.
For more details see: [the 'Array' STOP section](#arraystop--arraystop)
### Promise proxies