From 9bee51f1d3f9b0b55d259a4ab10fcf956489874f Mon Sep 17 00:00:00 2001 From: "Alex A. Naanou" Date: Mon, 6 Feb 2023 02:43:20 +0300 Subject: [PATCH] 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 --- Promise.js | 58 +++++++++++++++++++++++++++++++++++++++++++++------- README.md | 14 +++++++++++++ package.json | 2 +- 3 files changed, 66 insertions(+), 8 deletions(-) diff --git a/Promise.js b/Promise.js index b41b88e..2ec21b8 100644 --- a/Promise.js +++ b/Promise.js @@ -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) }, diff --git a/README.md b/README.md index d89dccf..a300d90 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,10 @@ Library of JavaScript type extensions, types and utilities. - [`Promise.iter(..)` / `promise.IterablePromise(..)`](#promiseiter--promiseiterablepromise) - [`.iter()`](#promiseiter) - [`.iter()`](#promise-iteriter) + - [`Promise.seqiter(..)` / `promise.IterableSequentialPromise(..)`](#promiseseqiter--iterablesequentialpromise) + - [`.seqiter()` / `.seqiter()`](#promiseseqiter--promise-iterseqiter) + - [`Promise.seqstartiter(..)` / `promise.IterableSequentialStartPromise(..)`](#promiseseqiter--iterablesequentialstartpromise) + - [`.seqstartiter()` / `.seqstartiter()`](#promiseseqstartiter--promise-iterseqstartiter) - [`.map(..)` / `.filter(..)` / `.reduce(..)`](#promise-itermap--promise-iterfilter--promise-iterreduce) - [`.between(..)`](#promise-iterbetween) - [`.flat(..)`](#promise-iterflat) @@ -1681,6 +1685,16 @@ Return a shallow copy of the current promise iterator. ``` +#### `Promise.seqiter(..)` / `promise.IterableSequentialPromise(..)` + +#### `.seqiter()` / `.seqiter()` + +#### `Promise.seqstartiter(..)` / `promise.IterableSequentialStartPromise(..)` + +#### `.seqstartiter()` / `.seqstartiter()` + + + #### `.map(..)` / `.filter(..)` / `.reduce(..)` Methods similar but not fully equivalent to `Array`'s diff --git a/package.json b/package.json index 6152d9d..e0fe655 100644 --- a/package.json +++ b/package.json @@ -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": {