Closed Raynos closed 10 years ago
The problems with such methods have been discussed at length in promise library repos, e.g. kriskowal/q#374, kriskowal/q#159, kriskowal/q#171, kriskowal/q#328. ES6 also makes them much less useful, generally, since you can do
Promise.all([pA, pB, pC]).then(([a, b, c]) => { ... })
instead of
Promise.whatever({ a: pA, b: pB, c: pC }).then(function (obj) { obj.a; obj.b; obj.c; });
the discussion in those issues does not explain it well other then "slippery slope". If you take a look at the continuable-para
implementation it's a simple three state machine
var list = require('continuable-list')
var hash = require('continuable-hash')
module.exports = function (obj, cb) {
if(Array.isArray(obj))
return list(obj, cb)
else if('object' === typeof obj)
return hash(obj, cb)
else
return list([].slice.call(arguments))
}
I could imagine that Promise.all
is another 2 state machine with if(isIterable()) { currentImplementation() } else { propertiesImplementation() }
My other use case for this is to have say a hash of teachers and wanting to fetch them asynchronously.
If I fetch them asynchronously as an array I would still do
Promise.all(...).then(function (list) {
var teacherHash = list.reduce(function (acc, value) {
acc[value.name] = value
return acc
}, {})
})
Having Promise.all
support an object would remove this conversion step.
@domenic note that before I used continuable-para
I authored and used continuable-list
& continuable-hash
as explicit and independent flow control primitives. From personal experience it's tedious to use & import both when the alternative is just using a single parallel function that works on the common structures.
Anything more complex is obvouisly out of scope and should not be in the core Promise
definition
Well, in promises_unwrapping it actually takes an iterable.
However, assuming the usual Promise.all
that works on Arrays.
I am not convinced by the arguments in 374 either. The obvious thing to do is to check for a non-primitive and only use enumerable own properties as returned by Object.keys()
(as implied in the last comment in that issue but ignored). Arrays (Array.isArray
) and Promises (Promise.isPromise
) are special cased and arrays with custom properties are not considered for those custom properties.
If you have reasonable code that needs to pass an Error object as an argument to Promise.all()
, I would like to see it. Even if you had, it would be treated like any other object.
If the arguments mentioned in 374 are the only ones, I will probably implement this in my library.
In general overloading and return-type polymorphism is discouraged. If this becomes a popular user-space extension we could consider Promise.allObject
or similar. But it is not in the scope of the September 2013 TC39 consensus, so closing for now.
Promise.all takes an array of promises and returns a promise for an array.
This form of doing parallel execution is useful.
Another form of parallel execution that is useful is something that takes an object of key to promise and returns a promise for an object of key to value of promise at that key.
The majority of my parallel execution flow control is covered by a user land module called
continuable-para
that supports those two syntaxes. (the third syntax can be done with ES6 splat notation).It would be a bit weird to have to use a 3rd party module for the object literal style parallel execution and use the browsers
Promise.all
for the array version.