Skip to main content

Promises in Code




To see more general explanations of promises: Promises and Deferreds - How I Stared To Like Them

At a basic level what Promises do is the same thing as passing a callback to a function.

function myFunc(callback){...}

myFunc(alert);
var promise = myFunc();
promise.then(alert);

But it is easy to get too many callbacks (if you work without promises), you need at least two, one for error and one for success. Functions need some arguments and you end up with a monster like:

myUgly(success, error, param1, param2, param3)

or move to a config object:

myBetter({success: success, error: error});


When I want to add another success function it gets uglier:

myBetter({successes: [success1, success2], error: error});


The same functionality with promises will be probably more verbose but I think this is a good thing. The code below is much more maintainable and extensible:

var promise = myPrecious({param1, param2, param3});
promise.when(success1);
promise.when(success2);
promise.when(success3);
promise.fail(error);

This two code examples may may look very similar to you but in my opinion second one is much more elegant, clean and obvious about what is happening.

It gets even better when you think about waiting for a couple of things to happen.
The easiest solution would be something like this underscore after:


var renderNotes = _.after(notes.length, render);
_.each(notes, function(note) {
  note.asyncSave({success: renderNotes});
});
What it's doing is just storing a variable in a closure and counting invocations of the function. With an underscore it's hidden behind a nice abstraction but for me it looks like a hack.

var runs = 10;
function afterAll(){
  if(runs-- > 0) return;
  //do something useful
}
ajax1(afterAll);
ajax2(afterAll);
...


Now look at similar code but with promises (from Q.js):

//notes is array of promises

Q.all(notes).when(afterAll);



jQuery

For jQuery this will look similar:

var promise1 = $.ajax("/myServerScript1");
var promise2 = $.ajax("/myServerScript2");
 
$.when(promise1, promise2).done(function(response1, response2){
  // Handle both responses
});


Code examples were not tested but some of them were copied from other sites so they may work. I've created them only for explanation purposes.



Comments

Popular posts from this blog

How to simulate slow connection (developer proxy in Node.js)

Update: If you use Chrome then you can use "Throttling" so simulate slow network for all your assets. This should be easier than proxy.


Toggle device modeChoose Network type.Refresh the page




https://developer.chrome.com/devtools/docs/device-mode 



Proxy:



For some time I wanted to use some proxy for development and testing of eg. slow internet connection, but it was hard to find something useful and free. I know there is Charles but buy it to use it at most one in a month is not for me.

I started thinking about Node.js, maybe I can write proxy for me? But fortunately I found one.

https://github.com/nodejitsu/node-http-proxy

With this module I can write really short code to create slow server:


var http = require('http'), httpProxy = require('http-proxy'); httpProxy.createServer(function (req, res, proxy) { var buffer = httpProxy.buffer(req); setTimeout(function () { proxy.proxyRequest(req, res, { host: 'localhost', port: 8080, …

How to use NPM packages from private repositories on bitbucket

Using Node.js you want to use NPM packages for reusable parts of the apps you create, that is a common sense. At the same time not everything makes sense as a public module unfortunately. Right now we are using Bitbucket at work for private repositories but there is a problem. How to use them as NPM modules? We do not want to publish them to the public npmjs.org but still want to have an ability to install them easily.

After googling and experimenting I have found simple solution.
First create new user in your organization with obscure password and give it read access to the repo. It is best to assign really obscure password but do not fool yourself. This is convenient but you must sacrifice security a bit. You should always consider how in your context that would be important.

Change example from below to:
user - username
PASS - password of the user
organization - owner of the project (you can find it in bitbucket url to your project)
project - your project name

"dependencies&…