-
-
Notifications
You must be signed in to change notification settings - Fork 927
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
Promises #1
Comments
Indeed, you probably want to implement Promises/A+, such that your implementation passes the compliance test suite. |
Thanks for the bug report. My implementation is currently pretty naive. I'm not sure I'll be able to use the ES6 API since I return thennables that are also |
You should just use promiscuous, tiny and A+ compliant |
It's recommended you use bluebird ( https://github.com/petkaantonov/bluebird ) or es6-promise ( https://github.com/jakearchibald/es6-promise ) The former for performance & error handling, the latter for ES6 compliance. |
+1 for bluebird, as this keeps in line with Mithril's existing performance goals. |
What's the use case for these?
The Bluebird core is 13178 bytes when uglified and gzipped. That's about the size of Mithril before any size reduction. Promiscuous, without its |
@pygy Good point regarding bluebird size - perhaps the built-in implementation can be used as the fallback unless a more thorough library (such as bluebird) is available. |
@pygy performance, correctness, kilobytes. Pick two. |
@pygy it's used for the assignment syntax for m.request, e.g. var users = m.request({method: "GET", url: "/users"}) This lets people create terser, more readable controllers, e.g. var ctrl = function() {
this.users = m.request(...);
} instead of var ctrl = function() {
this.users = m.prop([]);
m.request(...).then(this.users);
} Regarding A+ compliance, I'm not sure I see the benefits of adding a big implementation into core (and for that matter, what the benefits of compliance are). As I understand, if you're an app developer doing hardcore promise stuff, you can "fix" non-compliant thennables by passing it into one of the existing libraries. I've documented all the use cases that I'm expecting from application developers in terms of thennable usage, but if someone could give me a gist showing me other real-life-ish cases that should be taken into consideration and that I'm not accounting for, I'd appreciate the insight. My biggest concern right now is that I don't want to swallow exceptions that a developer would expect to see on the console (stuff like null ref exceptions, etc). The |
@lhorie promises A+ have very specific rules about error handling that when followed allow writing throw safe code. If a user forgets to wrap a fake mithril promise in a real promise and does realPromise.then(function (v) {
return fakeMithrilPromise()
}) then it breaks the ability to write throw safe code in a subtle fashion. Some promise libraries (like I think bluebird cc @petkaantonov @spion) will see that a thenable is returned and it's not a real promise and will cast it into a real promise to ensure that the ability to write throw safe code is upheld. Another obvious problem is people seeing a mithril promise and thinking "i dont need to read the docs, its a real promise I know how those work" and then wasting hours debugging their code because your promises are subtly different. |
For me, this is the biggest point. Principle of least surprise is not to be underestimated. |
If you chose to wrap another lib, I think that this would preserve the getter-setter nature of thenables: promise = new Promise(function(resolve, reject){...})
prop = m.prop()
prop.then = promise.then.bind(promise)
prop.then(prop) If you call your thenables "thenables", rather than promises, it will dispell the confusion. Regarding exceptions, bluebird provides good debugging features for dev mode.
Developers can switch to something lighter but slower for production, if needed. There are few use cases for speedy promises on the client side. |
Do not recommend that. The place where you need the debugging features is production, not development. Debugging in development is trivial because you can reproduce things, restart your programs, make smaller test cases in your unit tests and add break points. Debugging in production is really hard because you can't do anything, all you can do is rely on the things you said up pro actively. This is where bluebird comes in. |
Just a quick update: I just took a quick look at promiscuous, but it uses The docs for Gonna need to spend some more time w/ it to see if there's any way to refactor promiscuous, but as of now, an Angular-like "jQuery-lite" approach looks like the most feasible option at the moment. |
This page clarifies a somewhat obscure point in the spec, which relates to the need for a This means there's no way to refactor promiscuous that doesn't involve reimplementing the setImmediate polyfill |
@lhorie Also read http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony A callback or promise must always be asynchronous. You will need You can use https://github.com/medikoo/next-tick which might be smaller then the setImmediate polyfill. |
Ok I think this is starting to become a bit of a rabbit hole. There are really three different issues here: 1 - throwing errors is not working as it should 2 - the current implementation does not guarantee that resolution is asynchronous 3 - it does not interop w/ 3rd party promises correctly (in the sense that you can't wrap others w/ Mithrils') The first issue is the one originally being reported, and it's pretty serious because it makes the API semi-useless in a pretty obvious way. This is fixed in origin/next and scheduled to be released in v0.1.1 The other 2 issues aren't as pressing - given Mithril's scope, I doubt these issues are preventing people from writing apps and I don't want to hold up the release of the other bug fixes (some of which are quite visible and relatively important), so I'm going to fix only the reported issue for now and revisit the a+ compliance issue after v0.1.1 release. |
Docs: mithril.component.md - Recommended changes
You provide a basise deferred implementation in mithril.
However, it is quite erm... bad.
Not only it uses the old deferred API in favor of the ES6 promise contructor - it doesn't provide type safety at all which is a major part of promises.
http://jsfiddle.net/3na87/
(correct behavior btw http://jsfiddle.net/yN6wF/ works in Chrome and browsers that support promises, alternatively you can include a promise library)
Please consider reading some more about promises and perhaps improving your implementation. Please reassure me this is not just cargo culting.
The text was updated successfully, but these errors were encountered: