6 ms·
Write logic, not mechanics
- jahewson 15y agoThe code doesn't actually work though, the very first example is broken: function sum(a, b) { return a + b } sum = promised(sum) var a = defer() // make promise var b = sum(a, 1) var b = sum(b, 5) console.log(b) // eventually prints => 17 a.resolve(11) // fulfill promise Prints: [object Object]15
- gozala 15y agoI have already fixed that, it was a typo, I meant following instead: var deferred = defer() // make promise var a = deferred.promise var b = sum(a, 1) var c = sum(b, 5) console.log(c) // eventually prints => 17 deferred.resolve(11) // fulfill promise
- jahewson 15y agoEdit: cool, it works!
- deleted 15y ago[deleted]
- streptomycin 15y agoThe typoed syntax was nicer than the real syntax, unfortunately.
- ricardobeat 15y agoYou were writing an article about it and didn't get it right on the first time - maybe that's the reason more people don't use it.
- skrebbel 15y agoThat, or a majority of the JS coding crowd is too novice to appreciate maintainable code better than copying and pasting "simple" plumbing all over the place.
- alexchamberlain 15y agoA very well thought out article.
- lucian1900 15y agoThis is one of the simplest implementations of deferreds I've seen in JS so far.
- drostie 15y agoIt looks like a bunch of us have had the same idea for Node.js. I wrote for example this: https://github.com/drostie/ducky/blob/master/promises.js https://github.com/drostie/ducky/blob/master/promises.js I've abandoned it at this point for a very particular reason: operators don't work well in this phrasing. That is, the example case given in the above discussion: function makeView(templateURI, dataURI) { var template = readURI(templateURI), data = readURI(dataURI); return Mustache.render(template, data); } ...while it's not bad, also doesn't actually try to "write logic", in a post that's about "write logic, not mechanics." What you really want to do is much more complicated because the example code starts to look ugly: var userPromise = db.getUser(data.session); return userPromise.attr("role").equals("admin").then( render(open("yay.xml"), db.send(data.request)), render(open("no_permissions.xml"), {}) ); Don't get me wrong, I still like the idea and think that there might be a very promising way to do this sort of work in Node. Certainly I prefer those five lines to always writing: db.getUser(data.session, function (err, user) { if (err) return callback(err); if (user.role === "admin") { db.send(data.request, function (err, reply) { if (err) return callback(err); render_file("yay.xml", reply, callback); }); } else { render_file("no_permissions.xml", {}, callback); } }); But as much as I really don't like that lame error stuff which breaks in a stiff wind, I also really want to be cautious about the exchange of these two lines: if (user.role === "admin") { userPromise.attr("role").equals("admin").then( What we really want, I guess, is some sort of mesoscopic system -- we still want operators and familiar control structures from our "micro" world, but we also want lazy evaluations and so on from our "macro" framework. This is not impossible but it is hard to get right. If my "ducky" project moves forward it will probably look something like this: return db.getUser(data.session)(function (user) { return (user.role === admin) ? render(open("yay.xml"), db.send(data.request)) : render(open("no_permissions.xml"), {}) }); You bubble up the lazy constructs with returns, the error handling gets internalized within the lazy constructs, and the "control-method" invocation allows you to build an arbitrary control structure with whatever object you have right now.
- suanniunai 15y agoASICS Ambassador Michael [url=http://www.asicssko.eu/]ASICS[/url] http://www.asicssko.eu/]ASICS[/url] Clarke has claimed his third Allan Border Medal, as well as [url=http://www.asicssko.eu/]ASICS http://www.asicssko.eu/]ASICS SKO[/url] Test Player of the Year, to cap a stunning first year as Australian Cricket Captain, whilst fellow Ambassador Shane Watson completed the ASICS [url=http://www.asicssko.eu/]ASICS http://www.asicssko.eu/]ASICS løbesko[/url] clean sweep, taking out the Australian One Day International and T20 Player of the [url=http://www.asicssko.eu/asics-gel-nimbus-c-15.html]Asics http://www.asicssko.eu/asics-gel-nimbus-c-15.html]Asics gel nimbus[/url]Year Awards. ASICS nimbus : http://www.asicssko.eu/ http://www.asicssko.eu/
- suanniunai 15y agoExperience the music exactly Beats by dre : http://www.beatsbydresale.org.uk/ http://www.beatsbydresale.org.uk/ the way the artist wants you to. Beats high definition headphones are precision-engineered to reveal the full Beats By Dr Dre : http://www.beatsbydresale.org.uk/monster-beats-in-ear-dre_17/ http://www.beatsbydresale.org.uk/monster-beats-in-ear-dre_17... digital music including the most sonically demanding rock,hip hop and R&B. With advanced speaker design, dr dre beats : http://www.beatsbydresale.org.uk/monster-beats-by-dre-studio-dre_13/ http://www.beatsbydresale.org.uk/monster-beats-by-dre-studio... delivers all beats by dre: http://www.beatsbydresale.org.uk/ http://www.beatsbydresale.org.uk/
- suanniunai 15y agoNike Shox : http://www.nikefree-dame.com/ http://www.nikefree-dame.com/ tilsynekomst og endda give folk mulighed for at edbånd Nike Free Run : http://www.nikefree-dame.com/ http://www.nikefree-dame.com/ organisationer, strækning og graden af beskyttelse dramatisk. anvendt Nike Free : http://www.nikefree-dame.com/ http://www.nikefree-dame.com/ på fødderne, således at hver af jer under slidbanen til effektiviteten af fulde. nike free : http://www.nikefree-dame.com/ http://www.nikefree-dame.com/
- suanniunai 15y ago[url=http://www.veskeronline.com/]marc http://www.veskeronline.com/]marc jacobs vesker[/url] [url=http://www.veskeronline.com/]chanel http://www.veskeronline.com/]chanel vesker[/url] [url=http://www.veskeronline.com/]burberry[/url] http://www.veskeronline.com/]burberry[/url] [url=http://www.veskeronline.com/]prada http://www.veskeronline.com/]prada vesker[/url] [url=http://www.veskeronline.com/]louis http://www.veskeronline.com/]louis vitton[/url] [url=http://www.veskeronline.com/]coach http://www.veskeronline.com/]coach vesker[/url] [url=http://www.veskeronline.com/]gucci http://www.veskeronline.com/]gucci vesker[/url] [url=http://www.veskeronline.com/]hermes[/url] http://www.veskeronline.com/]hermes[/url] coach vesker : http://www.veskeronline.com/ http://www.veskeronline.com/
- suanniunai 15y agomarc jacobs vesker,http://www.veskeronline.com/ http://www.veskeronline.com/ chanel vesker,http://www.veskeronline.com/ http://www.veskeronline.com/ burberry,http://www.veskeronline.com/ http://www.veskeronline.com/ prada vesker,http://www.veskeronline.com/ http://www.veskeronline.com/ louis vitton,http://www.veskeronline.com/ http://www.veskeronline.com/ coach vesker,http://www.veskeronline.com/ http://www.veskeronline.com/ gucci vesker,http://www.veskeronline.com/ http://www.veskeronline.com/ hermes,http://www.veskeronline.com/ http://www.veskeronline.com/ coach vesker : http://www.veskeronline.com/ http://www.veskeronline.com/
- pestaa 15y agoit’s possible to make sync function async it’s not the case other way round Is this terminology correct? I thought it is easier to make async functions sync by blocking it, and harder to unblock a sync one. Am I confusing this with something else?
- gozala 15y agoSorry for confusion, I meant indeed a sync / async APIs. You could easily wrap sync function to give it an async API in order to chain with functions that had async APIs, but it's not really possible other way round (not in JS).
- lucian1900 15y agoI think the OP refers to the syntax/API for each. If you're already using async APIs, adding a sync one that runs in a separate thread won't change much. On the other hand, you need something like CPS or coroutines to cleanly use an async function in a program mostly using sync APIs. Of course, if you have the right tools (CPS/coroutines) you can make any async API look sync, as you said.
- gozala 15y agoI mainly was referring to JS where we don't have coroutines and there is no plans to have them either.
- shangaslammi 15y agoIt's a bit misleading way to put it, but more or less correct when talking about client-side JavaScript. There are essentially no blocking calls, so a "synchronous" function in this context just means a normal function which directly returns a value and "asynchronous" means a function that takes a callback. What the quoted bit boils down to is that any function that returns normally can be converted into a function that calls a callback, but not the other way around.
- stcredzero 15y agoI will be down voted for saying so, but "than" and "then" seem to be reversed throughout the entire article. I would like to learn more about promises now.
- gozala 15y agoYou're absolutely right! My English is far from being perfect and in addition I was rushing to get this post out making bunch of mistakes. I tried to fix all the "than" "then" issues, thanks for pointing that out ;)
- stcredzero 15y agoI was thinking about promises, because I just wrote a procedurally generated universe in Javascript with over 2^100 locations. To do the procedural generation correctly, the Math.random() function has to be called in the same order every time for generating each "sector." I had used promises in Smalltalk, but never found an application super for them and was thinking that promises would be a way to code this cleanly.
- EtienneK 15y agoThe lack of semicolons in the article's examples makes me uneasy...
- pygy_ 15y agoOh noes!!! and his library starts with the dreaded exclamation point!!! -- another disgruntled JavaScripter. I know that people identify strongly with technical choices[0] (and if you feel uneasy, you're probably the victim of this natural inclination of ours[1]), but I'm tired of the semicolon drama here on HN. Could we please stop? -- [0] http://paulgraham.com/identity.html http://paulgraham.com/identity.html [1] or did I miss your sarcasm?
- possibilistic 15y agoI detect sarcasm. Especially given the headlines of the past week. Constructive post though, thanks!
- sergimansilla 15y agoWell put. It still puzzles me that promises and/or CPS don't have a greater adoption in the JavaScript community. I guess that what happens is that the concept of a callback is a very easy to understand one, but a system becomes more complicated and cumbersome (exponentially, I would say) with every new callback that is added to it. The real problem comes when creating big async applications in JavaScript based entirely in callbacks, as it is the norm now specially in NodeJS projects. Using callbacks to build complex applications is a sure way to un-maintainability.
- lobo_tuerto 15y agoI found this very useful for architecting larga javascript aps: http://speakerdeck.com/u/addyosmani/p/large-scale-javascript-application-architecture http://speakerdeck.com/u/addyosmani/p/large-scale-javascript...
- IsTom 15y agoCPS is best suited for intermediate code, it's not something to be written/read by humans as it's basically the same as goto.
- dreadpirateryan 15y agoFor any node.js devs out there, here is the promises library I've been using with great success: https://github.com/coolaj86/futures/tree/v2.0/future https://github.com/coolaj86/futures/tree/v2.0/future
- ricardobeat 15y agoThat last line return Mustache.render(template, data) Isn't exactly equivalent to the non-promise one, since now `Mustache.render` is async, is it?
- wonnage 15y agoIt's much more useful now, IMO. Now you can chain an error handler onto your view's render method, and the level of abstraction becomes "I couldn't render the view" rather than "I couldn't get some JSON from the server". Functionally the behavior is the same - you're still going to have to gate an asynchronous stream of actions (make sure steps a, b, c have completed before d, etc.), but with this, you can describe that logic where it matters - renderView().then(attachHandlers).then..., instead of callback nesting hell (attachHandlers would have to be in renderView).
- gozala 15y agoYeah I had this comment there // Assuming Mustache.render = promised(Mustache.render) But my hope is that more libraries will be accepting promises in a future so one won't have to do the wrapping of a world around.
- wonnage 15y agoA good example of deferreds can be found in jQuery - every AJAX method returns a deferred that you can chain success, error, etc. handlers to. So it's not like this idea isn't a mainstream one. The main problem I see is that very few libraries handle receiving promises as arguments, probably because there isn't a standard/widely-used implementation of them. So your logic ends up being backwards, e.g you'd chain Mustache.render off of a jQuery success promise, rather than just passing the success promise in.
- gozala 15y agoWhat I'm suggesting is that promises don't need any special treatment. If you have a function that you want to feed a promise just wrap it: promised(Mustache.render). That's all it takes.
- stephank 15y agoIt strikes me that this developer chooses to write an abstraction on top of JS for solving his recurring problems, over simply using language features readily available. Promises are as much a pattern or mechanic as callbacks, but the latter feels far more natural in JS. The `promised` decorator is interesting, but it has problems: - The application I work on, and have in mind with this, would need just about every function decorated. - It doesn't account for methods, unless you're default decorating the method, ie.: `Foo.prototype.myMethod = promised(function(/* ... /) { / ... */ });` - Every decorated function takes a noticable performance hit, because things like `Function#apply` and concatenating `arguments` are relatively slow. - It doesn't sit well with me that the example rewrites a method on a prototype declared elsewhere: `console.log = promised(console.log)` Further, the article and library don't even scratch the surface of complicated async flows. Think async versions of common functional-style methods like `map`, `reduce`, etc. For example, a basic scenario from our own build process is: Scan a directory for template files, read them, compile them, then concatenate the result and write it out. We used to have a promise library to do all of this, from handling a build process to performing database queries. I discovered Async.js at some point and haven't look back since: https://github.com/caolan/async https://github.com/caolan/async
- MatthewPhillips 15y agoPromises are likely to be baked into JavaScript at some point in the future[1], so I would recommend becoming familiar with them now. Even if you don't use the pattern personally you will likely run into libraries that do use it once it is part of the spec. I don't too much like the promise pattern this article gives, Q is the definitive implementation: http://documentup.com/kriskowal/q/ http://documentup.com/kriskowal/q/ [1]http://wiki.ecmascript.org/doku.php?id=strawman:concurrency http://wiki.ecmascript.org/doku.php?id=strawman:concurrency
- gozala 15y agoJust to be clear this library implements just a subset of Q with exact same API, with only addition of `promised` wrapper. I'm convinced that this wrapper is a better way to deal with promises than dozens of utility functions that you have to learn about. For example Q.all is promised(Array) I find later more intuitive. That's not to say don't use Q! Q is brilliant piece of software and I'd be more than happy to see more people using it.