kriskowal/q — pull request #475 by kriskowal (2014-02-08 07:24:33+00:00)
Title: Draft of estimating time to completion

This is a request for comments on a new interface for estimating progress. The new kernel is an estimated time to completion for each promise. The estimate can be queried synchronously with `promise.getEstimate()` or observed asynchronously with `promise.observeEstimate(observer(estimate))`. Updates to the estimate can be provided with `deferred.setEstimate(estimate)`. The estimate must be a number of milliseconds like `Date.now()` and invalid values are interpreted as “never”, encoded as `Infinity`. Observing the ETC is facilitated by a new "estimate" message, which can conceivably cross a network boundary. The estimate message gets forwarded like any other when a pending promise becomes resolved, but each deferred has an opportunity to update the estimate when it is in control of the promise.

This illustrates solutions for composing estimates. The `then` method requests instead of a `progressed` handler, an estimate in milliseconds of how long the fulfillment handler will take. While `this` promise is pending, the composite estimated time to completion is the `this` promise's ETC plus the estimated milliseconds to complete the fulfillment handler. After the fulfillment handler is called, the returned promise “becomes” the result of the handler, which then can then issue updates for the composite estimate.

The `all` method watches for changes to the the estimated time to complete each of the input promises and the composite is always the maximum of the inputs.

The `delay` method uses `then` to wait for the input value, passing its delay time as the third argument. The delay begins in the fulfillment handler, which creates a pending promise and estimates the time to completion as being the time that the fulfillment handler was called plus the delay milliseconds, then returns that promise.

`thenResolve` is altered to use `all` to take advantage of the existing `max` logic. The ETC is the max ETC of the `this` promise and the argument promise.