Here is another example why you should start writing Coffeescript.
The business story in this example is rather simple - I need to load all document from a collection (named
Accounts), perform an asynchronous operation (
notifyOwner) on each of them, and save all of them back to DB after all
notifyOwner operations finish successfully. The following methods are available to achieve this simple task:
Account.find() #find all accounts
account.notifyOwner()
account.save()
All three methods are asynchronous and return a
jQuery promise which resolve with either the results or itself for chaining. Because there are multiple accounts involved, we will also need to take advantage of
jQuery.when.
Here is how we implement the business logic in Coffeescript
Account.find()
.then (accounts)->
$.when (account.notifyOwner() for account in accounts)...
.then (accounts...)->
$.when (account.save() for account in accounts)...
.done ->
console.log 'successfully notified all owners'
It takes advantage of coffeescript's splats feature to overcome jQuery.when's inability to take in an array of deferred.
#resolves only when all three deferred resolve)
jQuery.when(deferred1, deferred2. deferred3)
#immediately resolves with the array passed in)
jQuery.when([deferred1, deferred2. deferred3])
What Javascript does that Coffeescript translate to?
Account.find().then(function(accounts) {
var account;
return $.when.apply($, (function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = accounts.length; _i < _len; _i++) {
account = accounts[_i];
_results.push(account.notifyOwner());
}
return _results;
})());
}).then(function() {
var account, accounts;
accounts = 1 <= arguments.length ? [].slice.call(arguments, 0) : [];
return $.when.apply($, (function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = accounts.length; _i < _len; _i++) {
account = accounts[_i];
_results.push(account.save());
}
return _results;
})());
}).done(function() {
return console.log('successfully notified all owners');
});
If you don't mind a bit help from underscore, We probably can simplify the iteration logic:
Account.find().then(function(accounts) {
var account;
return $.when.apply($, (function() {
return _(accounts).map(function(account){
return account.notifyOwner();
});
})());
}).then(function() {
var accounts = 1 <= arguments.length ? [].slice.call(arguments, 0) : [];
return $.when.apply($, (function() {
return _(accounts).map(function(account){
return account.save();
});
})());
}).done(function() {
return console.log('successfully notified all owners');
});
So, that's clearly a lot more key strokes than Coffeescript but that's not the point. The point is how easy to read this Javascript version vs the Coffeescript version. Code could be written only once but it often times has to be read multiple times afterwards. Which version will you rather read?
Now, are you convinced?
Great writeup!
ReplyDeleteI am using coffeescript but didn't know the trick you showed here. Now I'm applying it to my code but still has some boilerplate code I hate to write. It is because jQuery.getJSON returns an array. I have below code
someHandler = (responses...) -> console.log(responses)
urls = ['a.json', 'b.json']
$.when(($.map(urls, (url) -> $.getJSON(url))...).then(someHandler)
I expect 'responses' passed to someHandler is always an array of responses even when there is only one urls. However, because getJSON returns an array like [data, 'success']. The 'responses...' is no good. I'm using a workaround
someHandler = (responses...) -> responses = if responses[1] instanceof Array then responses else [responses]
Have you had this problem? Any suggestions?
Thank you.
Guoliang Cao
Guoliang,
ReplyDeleteTry use underscore map instead of $.map which might flatten the resulting array unnecessarily for you. Underscore map always return an array.
Let me know it worked for you.
Kai
change control system I am impressed. I don't think Ive met anyone who knows as much about this subject as you do. You are truly well informed and very intelligent. You wrote something that people could understand and made the subject intriguing for everyone. Really, great blog you have got here.
ReplyDeleteFESHOP REDDIT Fe-acc18 TOR LINK FESHOP-CARD.RU I think this is an informative post and it is very useful and knowledgeable. therefore, I would like to thank you for the efforts you have made in writing this article.
ReplyDeleteUniccshop sign up free loaded cracked accounts activated I have read all the comments and suggestions posted by the visitors for this article are very fine,We will wait for your next article so only.Thanks!
ReplyDeleteUniccshop sign up free loaded cracked accounts activated I admire this article for the well-researched content and excellent wording. I got so involved in this material that I couldn’t stop reading. I am impressed with your work and skill. Thank you so much.
ReplyDeleteNice to be visiting your blog once more, has been months for me. Well this article that I've been waited for therefore long. i want this article to finish my assignment within the faculty, and it has same topic together with your article. Thanks, nice share.
ReplyDeleteBest Fullz Store High Valid And Refundable Time Trusted
Nice to be visiting your blog once more, has been months for me. Well this article that I've been waited for therefore long. i want this article to finish my assignment within the faculty, and it has same topic together with your article. Thanks, nice share.
ReplyDeleteFESHOP-JET2.RU LOGIN DOMAIN 2020
A very awesome blog post. We are really grateful for your blog post. You will find a lot of approaches after visiting your post. Fleet manager
ReplyDeleteus import data I am impressed. I don't think Ive met anyone who knows as much about this subject as you do. You are truly well informed and very intelligent. You wrote something that people could understand and made the subject intriguing for everyone. Really, great blog you have got here.
ReplyDeleteI exploit solely premium quality products -- you will observe these individuals on: sherlock email extractor 1.1
ReplyDeleteThank you a bunch for this with all of us you actually realize what you are talking about! Bookmarked. Please also seek advice from my site =). We could have a hyperlink change contract between us! importers data
ReplyDeleteThere you can download for free, see the first of these data. this site
ReplyDeleteVery informative post! There is a lot of information here that can help any business get started with a successful social networking campaign. nova versão do HappyMod APC disponÃvel
ReplyDeleteThere you can download for free, see the first of these data. CBT Mass Email Sender
ReplyDeleteAwesome article, it was exceptionally helpful! I simply began in this and I'm becoming more acquainted with it better! Cheers, keep doing awesome! office mac 2021
ReplyDeleteWhen your website or blog goes live for the first time, it is exciting. That is until you realize no one but you and your. office programm
ReplyDelete