-
Notifications
You must be signed in to change notification settings - Fork 393
Description
Promise progress is problematic for several reasons. One big one is that progress values are opaque (they might be numbers, objects, arrays, etc.). A promise library can't combine them in any meaningful way. For example, when.all
can't combine the progress values from its input promises. It must simply pass them through. This means that the promise returned by when.all
might receive heterogenous values: some are objects, some are numbers, etc. and the caller would have to write code to combine them.
I would put money on progress being used in 95+% of cases to track I/O operations in order to show the user some sort of progress indicator. There are other uses, but I've rarely seen them. One example is wire.js, which could (but doesn't currently) track progress toward wiring completion, which involves wiring a discrete number of components. Another example is tracking the progress of UI wizard steps (I'm not convinced that's actually a good use case, but I've seen it).
With that in mind, what if progress values were required to be a number between 0 and 1, literally representing "percent complete". That seems to have some interesting properties:
- It's likely fairly easy to compute. For anything with discrete steps, it's steps accomplished / total steps. e.g. For I/O, it's bytes read / total bytes.
- It's easy to combine via averaging for operations where all promises must fulfill (eg
when.all
,when.map
,when.reduce
, etc etc). For 2 promises,combined = (progress1 + progress2) / 2
, and by extension for N promises:combined = sum(progressValues) / progressValues.length
. I believe this works for sequential, and "parallel" tasks.- It's also associative:
progress2(a, progress2(b, c)) === progress2(progress2(a, b), c)
. which means that progress values from arbitrary operations (all, any, race) etc. can be combined easily, again via averaging:progress2(all(array1), p)
- It's also associative:
- There are other ways to combine:
when.any
andwhen.race
->Math.max.apply(progressValues)
(it's a race, so progress can be estimated by the one that appears to be winning)when.some
-> sort progress values in descending order, take top N, combine via average.when.settle
-> same aswhen.al
l?
I'm hoping that we can discuss here, and if this makes sense, talk to other promise library maintainers to get their thoughts as well.