I'm looking into BreezeJs and there samples are using Q.js for promises to handle asynchronous calls. John Papa is also using Q. JQuery has promises as well. What are the differences between the two?
问题:
回答1:
Both are based on the Promises/A standard and implement a then
method (though only current jQuery, they once had a incompatible pipe
instead of then
). However, there are a few differences:
- Q has exception handling. All thrown errors in the async
then
callbacks will be caught and reject the promise (and will only get re-thrown if you call.end()
). Not sure whether I personally like that. It's the standardized way which jQuery does not follow, rejecting fromthen
in jQuery deferreds is much more complicated. - Q promises are resolved with a single value/reason (like you return/throw it from
then
), while jQuery allows multiple arguments inresolve
/reject
calls on its Deferreds. - Q has lots of Proxy methods which will allow you to modifiy future values
- Q has
.all
and similiar, which are more complicated with jQuery ($.when.apply($, […])
). - Q does explicitly work with ticks in the event loop and guarantees asynchronity, while jQuery can be synchronous as well. This is now required by the Promises A/+ specification.
… which is basically Promises/B. As you can see, the Q
API is more powerful, and (imho) better designed. Depending on what you want to do, Q
could be the better choice, but maybe jQuery (especially if already included) is enough.
回答2:
JQuery's promise implementation of the Promises/A spec has some real issues. The following link describes them far better than I can: missing-the-point-of-promises
回答3:
Bergi's answer covers things fairly well. I wanted to add, though, that we've created a guide for Q users coming from jQuery. To summarize the relevant sections:
- Q handles exceptions, allowing you to handle all errors through a uniform interface.
- Q focuses on chaining with all its methods, whereas jQuery only allows chaining from
then
/pipe
. - Q promises guarantee asynchronicity, thus avoiding the control flow hazards and race conditions that result from jQuery's sometimes-sync, sometimes-async behavior.
- Q promises are always fulfilled with a single value or rejected with a single reason, just like synchronous functions always either return a single value or throw a single exception.
- Q enforces a separation between the deferred and the promise, whereas jQuery merges them into one object with the option of separating them.
- Q does not track a context object along with the fulfillment or rejection, since this has no parallel for synchronous functions (i.e., you never return a value as well as a
this
in which the caller must run). So there is noresolveWith
orrejectWith
. - Q uses Promises/A+ terminology; the main difference is that Q uses "fulfilled" where jQuery uses "resolved," and in Q "resolved" means something more subtle.
The guide also contains a table paralleling jQuery and Q promise APIs.