mirror of
https://github.com/flynx/types.js.git
synced 2025-10-28 18:10:08 +00:00
more work on iterable promises, still not ready...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
aa22c819ec
commit
3fada85cd9
78
Promise.js
78
Promise.js
@ -114,6 +114,11 @@ object.Constructor('IterablePromise', Promise, {
|
||||
: [] }) },
|
||||
// NOTE: this does not return an iterable promise as we can't know
|
||||
// what the user reduces to...
|
||||
// NOTE: the items can be handled out of order because the nested
|
||||
// promises can resolve in any order.
|
||||
// XXX write how to go around this...
|
||||
// NOTE: since order of execution can not be guaranteed there is no
|
||||
// point in implementing .reduceRight(..)
|
||||
reduce: function(func, res){
|
||||
return this.constructor(this.__list.flat(),
|
||||
function(e){
|
||||
@ -121,17 +126,6 @@ object.Constructor('IterablePromise', Promise, {
|
||||
return [] })
|
||||
.then(function(){
|
||||
return res }) },
|
||||
/*/ XXX this is wrong...
|
||||
reduceRight: function(func, res){
|
||||
return this.constructor(this.__list.flat().reverse(),
|
||||
function(e){
|
||||
res = func(res, e)
|
||||
return [] })
|
||||
.then(function(){
|
||||
return res }) },
|
||||
// XXX this is wrong...
|
||||
reverse: function(){
|
||||
return this.constructor(this.__list.flat().reverse()) },
|
||||
flat: function(depth=1){
|
||||
return this.constructor(this.__list.flat(),
|
||||
function(e){
|
||||
@ -142,11 +136,41 @@ object.Constructor('IterablePromise', Promise, {
|
||||
: depth != 0 ?
|
||||
e
|
||||
: [e] }) },
|
||||
// XXX REVERSE...
|
||||
// XXX BUG:
|
||||
// await Promise.iter([1, Promise.iter(['a', ['b', 'c']]), [2, 3], 4])
|
||||
// .flat()
|
||||
// -> [ 1, 'a', [ 'b', 'c' ], 2, 3, 4 ]
|
||||
// await Promise.iter([1, Promise.iter(['a', ['b', 'c']]), [2, 3], 4])
|
||||
// .flat()
|
||||
// .reverse()
|
||||
// -> [ 4, 2, 3, [ 'b', 'c', 'a' ], 1 ]
|
||||
// ...should be:
|
||||
// -> [ 4, 2, 3, [ 'b', 'c' ], 'a', 1 ]
|
||||
// it's odd we are not seeing this in other places...
|
||||
reverse: function(){
|
||||
return this.constructor(this.__list
|
||||
.map(function(elems){
|
||||
return elems && elems.then ?
|
||||
elems.then(function(res){
|
||||
return res
|
||||
.reverse()
|
||||
.flat() })
|
||||
: elems })
|
||||
.reverse()
|
||||
.flat()) },
|
||||
|
||||
// compatibility with root promise...
|
||||
iter: function(){
|
||||
return this.constructor(this.__list.flat()) },
|
||||
//*/
|
||||
return this.constructor(
|
||||
// clone and unwrap the .__list
|
||||
this.__list
|
||||
.map(function(elems){
|
||||
return elems && elems.then ?
|
||||
elems.then(function(res){
|
||||
return res.flat() })
|
||||
: elems })
|
||||
.flat()) },
|
||||
|
||||
// XXX do we need these?
|
||||
// .pop()
|
||||
@ -229,7 +253,13 @@ object.Constructor('IterablePromise', Promise, {
|
||||
// manually handle the stop...
|
||||
// - another issue here is that the stop would happen in order of
|
||||
// execution and not order of elements...
|
||||
// XXX add support for list as a promise....
|
||||
__new__: function(_, list, handler){
|
||||
// handle: IterablePromise(<list>, <mode>)
|
||||
if(typeof(handler) == 'string'){
|
||||
mode = handler
|
||||
handler = undefined }
|
||||
|
||||
// instance...
|
||||
var promise
|
||||
var obj = Reflect.construct(
|
||||
@ -246,12 +276,16 @@ object.Constructor('IterablePromise', Promise, {
|
||||
|
||||
if(promise){
|
||||
// clone/normalize...
|
||||
list = list
|
||||
.map(function(e){
|
||||
return (e && e.then) ?
|
||||
e.then(function(e){
|
||||
return [e] })
|
||||
: [e] })
|
||||
list =
|
||||
list instanceof Promise ?
|
||||
// XXX broken by reverse/flat but seems to work OK with others...
|
||||
[list]
|
||||
: list
|
||||
.map(function(e){
|
||||
return (e && e.then) ?
|
||||
e.then(function(e){
|
||||
return [e] })
|
||||
: [e] })
|
||||
|
||||
if(handler){
|
||||
// NOTE: this is recursive to handle expanding nested promises...
|
||||
@ -262,7 +296,7 @@ object.Constructor('IterablePromise', Promise, {
|
||||
return elems
|
||||
.map(handle)
|
||||
.flat() })
|
||||
: elem
|
||||
: elem
|
||||
.map(handler)
|
||||
.flat() }
|
||||
|
||||
@ -483,6 +517,10 @@ var PromiseProtoMixin =
|
||||
module.PromiseProtoMixin =
|
||||
object.Mixin('PromiseProtoMixin', 'soft', {
|
||||
as: ProxyPromise,
|
||||
|
||||
// XXX
|
||||
iter: function(){
|
||||
return IterablePromise(this) },
|
||||
})
|
||||
|
||||
PromiseProtoMixin(Promise.prototype)
|
||||
|
||||
36
README.md
36
README.md
@ -70,6 +70,8 @@ Library of JavaScript type extensions, types and utilities.
|
||||
- [`<promise-coop>.then(..)`](#promise-coopthen)
|
||||
- [Promise iteration](#promise-iteration)
|
||||
- [`Promise.iter(..)` / `promise.IterablePromise(..)`](#promiseiter--promiseiterablepromise)
|
||||
- [`<promise>.iter()`](#promiseiter)
|
||||
- [`<promise-iter>.iter()`](#promise-iteriter)
|
||||
- [`<promise-iter>.map(..)` / `<promise-iter>.filter(..)` / `<promise-iter>.reduce(..)`](#promise-itermap--promise-iterfilter--promise-iterreduce)
|
||||
- [`<promise-iter>.flat(..)`](#promise-iterflat)
|
||||
- [`<promise-iter>.then(..)` / `<promise-iter>.catch(..)` / `<promise-iter>.finally(..)`](#promise-iterthen--promise-itercatch--promise-iterfinally)
|
||||
@ -1452,8 +1454,8 @@ promise, and it is similar to a _generator_ in that it allows iteration over the
|
||||
contained values and chaining of operations but unlike `Promise.all(..)` this
|
||||
iteration occurs depth-first instead of breadth first.
|
||||
|
||||
Essentially one can think of _promise iterators_ vs. _generators_ as the former
|
||||
being internally controlled and asynchronous while the later being externally
|
||||
One can think of _promise iterators_ vs. _generators_ as the former being
|
||||
internally controlled and asynchronous while the later being externally
|
||||
controlled and synchronous.
|
||||
|
||||
Here is a traditional example using `Promise.all(..)`:
|
||||
@ -1515,8 +1517,27 @@ XXX should we support infinite generators as input?
|
||||
#### `Promise.iter(..)` / `promise.IterablePromise(..)`
|
||||
|
||||
Create an _iterable promise_
|
||||
|
||||
```bnf
|
||||
Promise.iter(<array>)
|
||||
Promise.iter(<promise>)
|
||||
-> <promise-iter>
|
||||
```
|
||||
|
||||
#### `<promise>.iter()`
|
||||
|
||||
```bnf
|
||||
<promise>.iter()
|
||||
-> <promise-iter>
|
||||
```
|
||||
|
||||
|
||||
#### `<promise-iter>.iter()`
|
||||
|
||||
Return a shallow copy of the current iterator.
|
||||
|
||||
```bnf
|
||||
<promise-iter>.iter()
|
||||
-> <promise-iter>
|
||||
```
|
||||
|
||||
@ -1545,7 +1566,7 @@ and [`.reduce(..)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe
|
||||
|
||||
```bnf
|
||||
<promise-iter>.reduce(<handler>, <state>)
|
||||
-> <promise-iter>
|
||||
-> <promise>
|
||||
|
||||
<handler>(<state>, <elem>)
|
||||
-> <state>
|
||||
@ -1558,6 +1579,15 @@ Note that these are different to `Array`'s equivalents in some details:
|
||||
this is because the index with _out-of-order_ and _depth-first_ execution the
|
||||
index is unknowable and the container is a promise/black-box.
|
||||
|
||||
This is especially critical for `.reduce(..)` as iteration in an order different
|
||||
from the order of elements _can_ affect actual result if this is not expected.
|
||||
|
||||
`.reduce(..)` is also a bit different here in that it will return a basic
|
||||
`<promise>` object as we can't know what will it will reduce to.
|
||||
|
||||
Note that since `.reduce(..)` order can not be guaranteed there is no point
|
||||
in implementing `.reduceRigth(..)`.
|
||||
|
||||
|
||||
#### `<promise-iter>.flat(..)`
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user