iterable promise seems to be ready...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2020-11-17 21:35:04 +03:00
parent a7e331e9b5
commit cc223ac031
2 changed files with 84 additions and 25 deletions

View File

@ -9,11 +9,13 @@
var object = require('ig-object')
//var {StopIteration} = require('./Array')
/*********************************************************************/
// XXX does this need to be a distinct object???
// XXX does this need to be a distinct object/constructor???
Promise.cooperative = function(){
var handlers
return object.mixinFlat(
@ -47,36 +49,89 @@ var IterablePromise =
module.IterablePromise =
Promise.iter =
object.Constructor('IterablePromise', Promise, {
// XXX
// XXX do we need this to be public???
__list: null,
// iterator methods...
//
// These will return a new IterablePromise instance...
//
// NOTE: these are different to Array's equivalents in that the handler
// is called not in the order of the elements but rather in order
// of promise resolution...
// NOTE: index of items is unknowable because items can expand on
// contract depending on handlrs (e.g. .filter(..) can remove
// items)...
map: function(func){
return IterablePromise(this.__list, function(e, i){
return [func(e, i)] }) },
return this.constructor(this.__list, function(e){
return [func(e)] }) },
filter: function(func){
return IterablePromise(this.__list, function(e, i){
return func(e, i) ?
return this.constructor(this.__list, function(e){
return func(e) ?
[e]
: [] }) },
// XXX
reduce: function(func, res){
// XXX
},
return this.constructor(this.__list,
function(e){
res = func(res, e)
return [] })
.then(function(){
return res }) },
flat: function(depth=1){
return IterablePromise(this.__list, function(e, i){
return this.constructor(this.__list, function(e){
return (e && e.flat) ?
e.flat(depth)
: e }) },
at: function(i){},
slice: function(){},
// XXX how does this support reduce???
// handler(e, i)
// NOTE: these return a Promise instance...
then: function(handler){
var that = this
return new Promise(function(resolve, reject){
// then...
object.parentCall(IterablePromise.prototype.then, that,
function(){
resolve(handler.call(this, ...arguments)) })
that.catch(reject) }) },
catch: function(handler){
var that = this
return new Promise(function(resolve, reject){
that.then(resolve)
// catch...
object.parentCall(IterablePromise.prototype.catch, that,
function(){
reject(handler.call(this, ...arguments)) }) }) },
finally: function(handler){
var that = this
return new Promise(function(resolve, reject){
// bind promise state to that...
that.then(resolve)
that.catch(reject)
// finally...
object.parentCall(IterablePromise.prototype.finally, that,
function(){
handler.call(this, ...arguments) }) }) },
//
// Promise.iter([ .. ])
// -> iterable-promise
//
// Promise.iter([ .. ], handler)
// -> iterable-promise
//
//
// handler(e)
// -> [value]
// -> []
//
__new__: function(_, list, handler=false){
//
// NOTE: element index is unknowable untill the full list is expanded
// as handler(..)'s return value can expand to any number of
// items...
// XXX we can make the index a promise, then if the client needs
// the value they can wait for it...
__new__: function(_, list, handler){
var promise
// instance...
@ -90,12 +145,10 @@ object.Constructor('IterablePromise', Promise, {
if(promise){
// apply handler(..) to the list...
// NOTE: the top level promises are not wrapped in arrays...
// XXX should this be aborted on reject???
// XXX we are keeping the top level promises unwrapped, is
// this correct???
// ...needs testing....
var c = 0
list = obj.__list =
// ...need to be able to do a deep abort...
list =
handler ?
list.map(function(block){
return (block instanceof Array ?
@ -104,18 +157,24 @@ object.Constructor('IterablePromise', Promise, {
.map(function(e){
// NOTE: we are counting actual expanded
// values and not the "blocks"...
var i = ++c
return (e && e.then && e.catch) ?
// promise...
e.then(function(v){
return handler(v, i) })
return handler(v) })
// basic value...
: handler(e, i) }) })
: handler(e) }) })
.flat()
: list.map(function(e){
: handler === undefined ?
list.map(function(e){
return e instanceof Promise ?
e
: [e] })
: list.slice()
Object.defineProperty(obj, '__list', {
value: list,
enumerable: false,
})
// handle promise state...
Promise.all(list)

View File

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