From 97b8fd6dd5c7a4b1cf54c68c5fb804a0801ea8a5 Mon Sep 17 00:00:00 2001 From: "Alex A. Naanou" Date: Mon, 13 Jun 2022 22:48:07 +0300 Subject: [PATCH] cleanup and docs... Signed-off-by: Alex A. Naanou --- Promise.js | 41 +++++++++++++++++++++++++----- README.md | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 108 insertions(+), 7 deletions(-) diff --git a/Promise.js b/Promise.js index 0f9c266..6bdc583 100644 --- a/Promise.js +++ b/Promise.js @@ -401,8 +401,27 @@ object.Constructor('IterablePromise', Promise, { lastIndexOf: promiseProxy('lastIndexOf'), includes: promiseProxy('includes'), + // + // .find() + // .find(, 'value') + // -> () + // + // .find(, 'result') + // -> () + // + // .find(, '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'), diff --git a/README.md b/README.md index 3965c76..9ce17c9 100644 --- a/README.md +++ b/README.md @@ -78,10 +78,13 @@ Library of JavaScript type extensions, types and utilities. - [`.concat(..)`](#promise-iterconcat) - [`.push(..)` / `.unshift(..)`](#promise-iterpush--promise-iterunshift) - [`.at(..)` / `.first()` / `.last()`](#promise-iterat--promise-iterfirst--promise-iterlast) + - [`.some(..)` / `.find(..)`](#promise-itersome--promise-iterfind) - [Array proxy methods returning ``](#array-proxy-methods-returning-promise-iter) - [Array proxy methods returning a ``](#array-proxy-methods-returning-a-promise) - [`.then(..)` / `.catch(..)` / `.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) - [`.as(..)`](#promiseas) - [`.(..)`](#promise-proxymethod) @@ -1674,6 +1677,46 @@ parent ``. XXX +#### `.some(..)` / `.find(..)` + +```bnf +.some() + -> + +.find() + -> +``` + +The main difference between `.some(..)` and `.find(..)` is in that the `` +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 `` +is resolved to... + +```bnf +.find() +.find(, 'value') + -> + +.find(, 'bool') + -> + +.find(, 'result') + -> +``` + +- `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 ``. + +These are similar to [`.some(..)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some) +and [`.find(..)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) +see them for more info. #### Array proxy methods returning `` @@ -1697,7 +1740,8 @@ XXX links... - `.indexOf(..)` - `.includes(..)` -- `.every(..)` / `.some(..)` +- `.every(..)` +- `.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 `` method can `throw` a STOP. + +For more details see: [the 'Array' STOP section](#arraystop--arraystop) + + ### Promise proxies