Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crazy progress use cases #6

Open
novemberborn opened this issue Dec 31, 2012 · 6 comments
Open

Crazy progress use cases #6

novemberborn opened this issue Dec 31, 2012 · 6 comments

Comments

@novemberborn
Copy link

#5 is concluding with an updated draft (https://gist.github.com/4400252) and an implementation. We now need a list of progress use cases and see if the behavior that flows from the spec is as expected.

@novemberborn
Copy link
Author

I've ported the fast/slow case with the following results:

$ node examples/fast-slow-progress.js
1
2
3
4
5
22
33
44
55

Which makes sense to me.

Source

@novemberborn novemberborn mentioned this issue Dec 31, 2012
@ForbesLindesay
Copy link
Member

Would be nice to see the resulting code for each case as well?

@novemberborn
Copy link
Author

Sorry, yes. Edited.

@domenic
Copy link
Member

domenic commented Jan 7, 2013

Off the top of my head:

  • returning a promise from the progress handler that is fulfilled after the original promise
  • returning a fast promise from one progress handler, plus returning a slow promise from a second progress handler; both fulfilled before fulfilling the original promise
  • returning a fast promise from one progress handler, plus returning a slow promise from a second progress handler; only the fast one fulfilled before fulfilling the original promise
  • combining those cases with the original promise being fast then chaining it to a slow promise

@domenic
Copy link
Member

domenic commented Jan 7, 2013

More:

  • try some of the above cases where either the fast or the slow promises eventually end up being rejections with .name === "StopProgressPropagation".
  • throw directly from onProgress handlers with .name === "StopProgressPropagation" instead of returning promises.
  • General chaining/propagation examples involving lots of handlers, some of which may return promises, some of which may return rejections, some of which may return StopProgressPropagators, and some of which may throw.
  • As above, but be sure to branch into multiple progress listeners for each step in the chain.

@novemberborn
Copy link
Author

  • returning a promise from the progress handler that is fulfilled after the original promise

This covers the scenario where the promise for the propagation value only fulfills after the original promise is fulfilled. Since progress can't be emitted once the promise is no longer pending, I think it should also hold that progress can't propagate once the promise the propagation originates from is no longer pending. Legendary already behaved this way, but it should be clarified in the spec.

A more complicated propagation scenario is when a fast promise is chained with a slow one:

var A = pending();
var B = pending();
var C = pending();
var spy = sinon.spy();

var p = A.promise.then(function(){
  return B.promise;
});
var q = p.then(null, null, function(){
  return C.promise;
});
q.then(null, null, spy);

A.progress();
A.fulfill();
C.fulfill();

// later
assert(!spy.called);

The spy shouldn't be called, since progress is propagated after A has been fulfilled, however propagation can't be prevented without canceling promises.

When A.progress() is called, it is propagated by calling progress on p's resolver, , which invokes the progress callback and returns a promise which in turn depends on the propagation from C's fulfillment value via q's resolver. Only canceling that promise can prevent propagation to the spy.

This would mean that support of Cancelation is required to implement Progress.

  • returning a fast promise from one progress handler, plus returning a slow promise from a second progress handler; both fulfilled before fulfilling the original promise
  • returning a fast promise from one progress handler, plus returning a slow promise from a second progress handler; only the fast one fulfilled before fulfilling the original promise

Assuming you mean "fast" and "slow" in respect to when they fulfill, their behavior is covered by the previous cases. Unless you mean a promise that emits progress quickly and slowly? The way it's specified right now, only the fulfillment value of a promise returned from a progress handler is used as the propagation value. Any progress emitted by that returned promise is ignored.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants