now Promise.seqiter(..) handlers will get triggered when previous handlers are done/resolved, and added .seqstartiter(..) to call the handlers as soon as the results are available regardless of whether the previous handler is done/resolved...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2023-02-06 02:43:20 +03:00
parent adcfe895c0
commit 9bee51f1d3
3 changed files with 66 additions and 8 deletions

View File

@ -880,7 +880,10 @@ object.Constructor('IterablePromise', Promise, {
// Promise.iter([ .. ]).iter(func)
// - func per element
// - func is called when an element is resolved/ready
// in order of resolution/readiness
// in order of resolution
// Promise.seqstartiter([ .. ]).iter(func)
// - func per element
// - func is called when an element is resolved/ready
// Promise.seqiter([ .. ]).iter(func)
// - func per element
// - func is called when an element is resolved/ready
@ -899,9 +902,9 @@ object.Constructor('IterablePromise', Promise, {
// XXX check if this behaves correctly (call order) on concatenation and
// other methods...
// XXX not sure if this is a viable strategy....
var IterableSequentialPromise =
module.IterableSequentialPromise =
object.Constructor('IterableSequentialPromise', IterablePromise, {
var IterableSequentialStartPromise =
module.IterableSequentialStartPromise =
object.Constructor('IterableSequentialStartPromise', IterablePromise, {
__pack: function(list, handler=undefined, onerror=undefined){
var seqiter = this.constructor
@ -924,7 +927,7 @@ object.Constructor('IterableSequentialPromise', IterablePromise, {
return res }
// NOTE: we are not handling the list here...
list = object.parentCall(IterableSequentialPromise.prototype.__pack, this, list)
list = object.parentCall(IterableSequentialStartPromise.prototype.__pack, this, list)
list = list instanceof SyncPromise ?
list.sync()
: list
@ -940,6 +943,46 @@ object.Constructor('IterableSequentialPromise', IterablePromise, {
})
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// XXX might also be a good idea to implement a version of the above to
// handle the next element only after the promise returned by the
// previous handler is resolved -- depth first...
// ...this would help prevent the await execution uncertainty, i.e.:
// console.log(1)
// // note that we are NOTE await'ing for the function here...
// (async function f(){
// console.log(2)})()
// console.log(3)
// -> prints 1, 2, 3
// and:
// console.log(1)
// (async function f(){
// // note the await -- this is the only difference...
// console.log(await 2)})()
// console.log(3)
// -> prints 1, 3, 2
// this is bad because of a handler has two execution paths one with
// an await and one without the order of actual handler execution can
// not be controlled unless we wait for the whole thing to resolve...
//
var IterableSequentialPromise =
module.IterableSequentialPromise =
object.Constructor('IterableSequentialPromise', IterableSequentialStartPromise, {
__handle: function(list, handler, onerror){
var prev = undefined
return object.parentCall(IterableSequentialPromise.prototype.__handle, this,
list,
// call the next handler only when the promise returned by
// the previous handler is resolved...
function(elem){
if(prev instanceof Promise){
return (prev = prev
.then(function(){
return handler(elem) })) }
return (prev = handler(elem)) },
...[...arguments].slice(2)) },
})
//---------------------------------------------------------------------
// Interactive promise...
@ -1247,7 +1290,7 @@ var PromiseMixin =
module.PromiseMixin =
object.Mixin('PromiseMixin', 'soft', {
iter: IterablePromise,
// XXX
seqstartiter: IterableSequentialStartPromise,
seqiter: IterableSequentialPromise,
interactive: InteractivePromise,
@ -1306,7 +1349,8 @@ object.Mixin('PromiseProtoMixin', 'soft', {
iter: function(handler=undefined, onerror=undefined){
return IterablePromise(this, handler, onerror) },
// XXX
seqstartiter: function(handler=undefined, onerror=undefined){
return IterableSequentialStartPromise(this, handler, onerror) },
seqiter: function(handler=undefined, onerror=undefined){
return IterableSequentialPromise(this, handler, onerror) },

View File

@ -76,6 +76,10 @@ Library of JavaScript type extensions, types and utilities.
- [`Promise.iter(..)` / `promise.IterablePromise(..)`](#promiseiter--promiseiterablepromise)
- [`<promise>.iter()`](#promiseiter)
- [`<promise-iter>.iter()`](#promise-iteriter)
- [`Promise.seqiter(..)` / `promise.IterableSequentialPromise(..)`](#promiseseqiter--iterablesequentialpromise)
- [`<promise>.seqiter()` / `<promise-iter>.seqiter()`](#promiseseqiter--promise-iterseqiter)
- [`Promise.seqstartiter(..)` / `promise.IterableSequentialStartPromise(..)`](#promiseseqiter--iterablesequentialstartpromise)
- [`<promise>.seqstartiter()` / `<promise-iter>.seqstartiter()`](#promiseseqstartiter--promise-iterseqstartiter)
- [`<promise-iter>.map(..)` / `<promise-iter>.filter(..)` / `<promise-iter>.reduce(..)`](#promise-itermap--promise-iterfilter--promise-iterreduce)
- [`<promise-iter>.between(..)`](#promise-iterbetween)
- [`<promise-iter>.flat(..)`](#promise-iterflat)
@ -1681,6 +1685,16 @@ Return a shallow copy of the current promise iterator.
```
#### `Promise.seqiter(..)` / `promise.IterableSequentialPromise(..)`
#### `<promise>.seqiter()` / `<promise-iter>.seqiter()`
#### `Promise.seqstartiter(..)` / `promise.IterableSequentialStartPromise(..)`
#### `<promise>.seqstartiter()` / `<promise-iter>.seqstartiter()`
#### `<promise-iter>.map(..)` / `<promise-iter>.filter(..)` / `<promise-iter>.reduce(..)`
Methods similar but not fully equivalent to `Array`'s

View File

@ -1,6 +1,6 @@
{
"name": "ig-types",
"version": "6.24.21",
"version": "6.24.22",
"description": "Generic JavaScript types and type extensions...",
"main": "main.js",
"scripts": {