mirror of
https://github.com/flynx/types.js.git
synced 2025-10-29 02:20:07 +00:00
reworked parts of iterable promise...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
cc223ac031
commit
a3fdf45578
122
Promise.js
122
Promise.js
@ -24,7 +24,16 @@ Promise.cooperative = function(){
|
||||
{
|
||||
get isSet(){
|
||||
return handlers === false },
|
||||
set: function(value){
|
||||
//
|
||||
// Resolve promise with value...
|
||||
// .set(value)
|
||||
// -> this
|
||||
//
|
||||
// Reject promise with value...
|
||||
// .set(value, false)
|
||||
// -> this
|
||||
//
|
||||
set: function(value, resolve=true){
|
||||
// can't set twice...
|
||||
if(this.isSet){
|
||||
throw new Error('Promise.cooperative().set(..): can not set twice') }
|
||||
@ -34,7 +43,9 @@ Promise.cooperative = function(){
|
||||
value.catch(handlers.reject)
|
||||
// resolve with value...
|
||||
} else {
|
||||
handlers.resolve(value) }
|
||||
resolve ?
|
||||
handlers.resolve(value)
|
||||
: handlers.reject(value) }
|
||||
// cleanup and prevent setting twice...
|
||||
handlers = false
|
||||
return this },
|
||||
@ -45,23 +56,49 @@ Promise.cooperative = function(){
|
||||
//---------------------------------------------------------------------
|
||||
// promise iterators...
|
||||
|
||||
// XXX should this be aborted on reject???
|
||||
var IterablePromise =
|
||||
module.IterablePromise =
|
||||
Promise.iter =
|
||||
object.Constructor('IterablePromise', Promise, {
|
||||
// XXX do we need this to be public???
|
||||
//
|
||||
// Format:
|
||||
// [
|
||||
// [ <value> ],
|
||||
// <promise>,
|
||||
// ...
|
||||
// ]
|
||||
//
|
||||
__list: null,
|
||||
|
||||
|
||||
// iterator methods...
|
||||
//
|
||||
// These will return a new IterablePromise instance...
|
||||
//
|
||||
// When called from a resolved promise these will return a new
|
||||
// resolved promise with updated values...
|
||||
//
|
||||
// When called from a rejected promise these will return a rejected
|
||||
// with the same reason promise...
|
||||
//
|
||||
//
|
||||
// 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)...
|
||||
// This the following can not be implemented here:
|
||||
// .slice(..)
|
||||
// .splice(..)
|
||||
// .at(..)
|
||||
// [Symbol.iterator]() - needs to be sync...
|
||||
// The followng methods are questionable:
|
||||
// .indexOf(..)
|
||||
// .includes(..)
|
||||
// .some(..) / .every(..)
|
||||
// .sort(..)
|
||||
map: function(func){
|
||||
return this.constructor(this.__list, function(e){
|
||||
return [func(e)] }) },
|
||||
@ -84,33 +121,37 @@ object.Constructor('IterablePromise', Promise, {
|
||||
: e }) },
|
||||
|
||||
|
||||
// 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) }) }) },
|
||||
// XXX do we need:
|
||||
// .pop()
|
||||
// .shift()
|
||||
// .first() / .last()
|
||||
// XXX these can change the "resolved" state...
|
||||
// ...i.e. return a pending promise when called from a fulfilled
|
||||
// promise....
|
||||
// .concat(..)
|
||||
// .push(..)
|
||||
// .unshift(..)
|
||||
// .first(..) / .last(..)
|
||||
|
||||
|
||||
// Overload .then(..), .catch(..) and .finally(..) to return a plain
|
||||
// Promise instnace...
|
||||
//
|
||||
// NOTE: .catch(..) and .finally(..) are implemented through .then(..)
|
||||
// so we do not need to overload those...
|
||||
then: function(onfulfilled, onrejected){
|
||||
return new Promise(
|
||||
function(resolve, reject){
|
||||
object.parentCall(IterablePromise.prototype.then, this,
|
||||
// NOTE: resolve(..) / reject(..) return undefined so
|
||||
// we can't pass them directly here...
|
||||
function(res){
|
||||
resolve(res)
|
||||
return res },
|
||||
function(res){
|
||||
reject(res)
|
||||
return res }) }.bind(this))
|
||||
.then(...arguments) },
|
||||
|
||||
|
||||
//
|
||||
@ -131,6 +172,17 @@ object.Constructor('IterablePromise', Promise, {
|
||||
// items...
|
||||
// XXX we can make the index a promise, then if the client needs
|
||||
// the value they can wait for it...
|
||||
//
|
||||
//
|
||||
// Clone the iterator...
|
||||
// Promise.iter([ .. ], false)
|
||||
// -> iterable-promise
|
||||
//
|
||||
// Create a rejected iterator...
|
||||
// Promise.iter(false)
|
||||
// -> iterable-promise
|
||||
//
|
||||
//
|
||||
__new__: function(_, list, handler){
|
||||
var promise
|
||||
|
||||
@ -140,15 +192,18 @@ object.Constructor('IterablePromise', Promise, {
|
||||
// NOTE: this is here for Promise compatibilty...
|
||||
if(typeof(list) == 'function'){
|
||||
return list.call(this, ...arguments) }
|
||||
// initial reject...
|
||||
if(list === false){
|
||||
return reject() }
|
||||
promise = {resolve, reject} }],
|
||||
IterablePromise)
|
||||
|
||||
if(promise){
|
||||
// apply handler(..) to the list...
|
||||
//
|
||||
// NOTE: the top level promises are not wrapped in arrays...
|
||||
// XXX should this be aborted on reject???
|
||||
// ...need to be able to do a deep abort...
|
||||
list =
|
||||
// apply the handler...
|
||||
handler ?
|
||||
list.map(function(block){
|
||||
return (block instanceof Array ?
|
||||
@ -164,11 +219,13 @@ object.Constructor('IterablePromise', Promise, {
|
||||
// basic value...
|
||||
: handler(e) }) })
|
||||
.flat()
|
||||
// normal constructor...
|
||||
: handler === undefined ?
|
||||
list.map(function(e){
|
||||
return e instanceof Promise ?
|
||||
e
|
||||
: [e] })
|
||||
// clone...
|
||||
: list.slice()
|
||||
|
||||
Object.defineProperty(obj, '__list', {
|
||||
@ -180,7 +237,6 @@ object.Constructor('IterablePromise', Promise, {
|
||||
Promise.all(list)
|
||||
.then(function(res){
|
||||
promise.resolve(res.flat()) })
|
||||
// XXX do we need to pass the results here???
|
||||
.catch(promise.reject) }
|
||||
|
||||
return obj },
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ig-types",
|
||||
"version": "3.7.8",
|
||||
"version": "3.7.9",
|
||||
"description": "Generic JavaScript types and type extensions...",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user