Overpromising with Multiple Promises in JavaScript

When dealing with multiple promises in JavaScript, it’s easy to “over-promise” or create too many promises. For example, let’s say you have a function that needs to return a promise because it also calls a function that returns a promise:

function doSomething() {
    var def = Q.defer();
    createPromise()
        .then(function onFulfilled() {
            console.log('first then');
            runTimeout();
        })
        .then(function onFulfilled() {
            console.log('second then');
            runTimeout();
            def.resolve();
        });
    return def.promise;
}

Instead, this function could be tightened up to look like this:

function doSomething() {
    return createPromise()
        .then(function onFulfilled() {
            console.log('first then');
            runTimeout();
        })
        .then(function onFulfilled() {
            console.log('second then');
            runTimeout();
        });
}

You don’t need to create and return a new promise. Just return the promise from the function that creates a promise. Sometimes, you can’t get away with this, but often you can.

This example also demonstrates how then returns a promise and resolves that promise only after the onFulfilled (or onRejected) function is executed. I didn’t use any onRejected functions to keep things simple.

Now, to give it more context with a contrived working example:

var i = 0;

// some function that does both synchronous and asynchronous stuff
// does not return a promise nor does it need to
function runTimeout(defObj, time) {
    time = time || 2000;
    console.log('timeout start.');
    setTimeout(function () {
        console.log('timeout finish.');
        if (defObj) {
            defObj.resolve();
        }
    }, time);
}

// some function that creates and returns a promise
function createPromise() {
    var def = Q.defer();
    console.log('createPromise ' + ++i);
    runTimeout(def);
    return def.promise;
}
 
// some function that executes a function that returns a promise
// also needs to do stuff after the promise is resolved
function doSomething() {
    return createPromise()
        .then(function onFulfilled() {
            console.log('first then');
            runTimeout();
        })
        .then(function onFulfilled() {
            console.log('second then');
            runTimeout();
        });
}

// another function that executes a function that returns a promise
// lots of nested promises at this point
function doMore() {
    console.log('start');
    doSomething()
        .then(createPromise)
        .then(function () {
            console.log('finish');
        });
}
 
doMore();

Test it in this JSFiddle.

You could argue that the functions/promises in this (naive) example could be ‘flattened,’ but when you are developing modules with dependencies on other modules, you can’t always flatten your functions into one chain of promises in one function. Furthermore, you wouldn’t want to because you’ve designed your modules to encapsulate specific logic (i.e. single responsibility principle) and that’s good.

If you’re really digging into JavaScript and promises then you ought to read the Promises/A+ specification for exact details on how then works. It’s a bit scary when you first look at it, but spec is outlined logically so it’s pretty easy to understand if you take the time.

JavaScript Function Declarations vs Function Expressions

I recently revisited the differences between Function Declarations (FD) and Function Expressions (FE). I wanted to see if there were any compelling reasons to use one over the other, or if both were considered acceptable. I’ve taken most of my thoughts from a blog post by Angus Croll. It’s worth a read if this is a new topic for you.

In general, FDs and FEs are interchangeable because they both create a function. However, there can be some interesting gotchas (as always with JavaScript).

Even though all browsers handle Function Declarations within non-function blocks (e.g. if), they are technically prohibited. The caveat is that each browser handles them in its own way.

function a() {
    if (false) {
        function b() { return 'Will it return?'; }
    }
    return b;
}
console.log(a()); // result depends on browser

A Function Declaration is scoped to itself and its parent. As a result, you can call it recursively and in the parent (it would be mostly useless otherwise). For example:

function minusOne(positiveNumber) {
    console.log(positiveNumber--);
    if (positiveNumber > -1) {
        return minusOne(positiveNumber);
    }
}
minusOne(2);   // 2 1 0

A Function Expression works just as well:

var minusOne = function (positiveNumber) {
    console.log(positiveNumber--);
    if (positiveNumber > -1) {
        return minusOne(positiveNumber);
    }
};
minusOne(2);   // 2 1 0

You could make the FE above a Named Function Expression (NFE) by naming the anonymous function subtractOne and it would still work. Furthermore, you could replace the recursive call to minusOne with subtractOne and it would work (assuming you named the anonymous function subtractOne). The following, however, would NOT work:

var minusOne = function subtractOne(positiveNumber) {
    console.log(positiveNumber--);
    if (positiveNumber > -1) {
        return minusOne(positiveNumber);
    }
};
subtractOne(2);   // subtractOne is not defined

You cannot call the named function outside of its assignment.

Here’s another function I wrote just for fun:

function moveToZero(number) {
    var absNumber = Math.abs(number);
    console.log(number);
    if (absNumber-- !== 0) {
        return moveToZero(number > -1 ? absNumber : ++number);
    }
}
moveToZero(2);  // 2 1 0
moveToZero(-2); // -2 -1 0

Function Expressions are more versatile. They are the essence of functional programming. You can create Function Expressions using anonymous functions. You can assign functions to objects as properties or, more specifically, assign them to prototypes. Immediatley Invoked Function Expressions (IIFEs) are considered Function Expressions. As Croll points out, currying and composing use FEs.

One of the caveats to Function Expressions is that functions are often created using anonymous functions, which can make debugging a pain. As a work around you can use Named Function Expressions, as seen in the examples above. However, NFEs are not supported in non-modern browsers (IE8 and below). Always something to keep in mind.

Many developers steer away from Function Declarations because they can be confusing. There aren’t many, if any, times you cannot replace a Function Declaration with a Function Expression. FEs are often favored for consistency and versatility.

Difference Between bin and sbin

Ever been curious about the difference between bin and sbin? The ‘s’ in sbin means ‘system’. Therefore, system binaries reside in sbin directories.

As you may have noticed, there are a number of different bin directories in Linux. The best reference I’ve found for an understanding of various Linux folders is man hier. It provides a brief explanation of the Filesystem Hierarchy Standard (FHS) in Linux. I’ve included a summary of the various bin and sbin definitions below:

/bin
    This directory contains executable programs which are needed
    in single user mode and to bring the system up or repair it.

/sbin
    Like /bin, this directory holds commands needed to boot the 
    system, but which are usually not executed by normal users.

/usr/bin
    This is the primary directory for executable programs. Most
    programs executed by normal users which are not needed for 
    booting or for repairing the system and which are not
    installed locally should be placed in this directory.

/usr/local
    This is where programs which are local to the site typically
    go.

/usr/local/bin
    Binaries for programs local to the site.

/usr/local/sbin
    Locally installed programs for system administration.

If you want to create your own scripts and make them available to all users, you’re pretty safe adding them to /usr/local/bin. If you want to run scripts using cron or crontab, simply use the full path to the command (i.e. /home/user/command).

What I do is add my scripts to my local bin (~/bin) and then I create a symbolic link in /usr/local/bin to the commands I want to make public. As a result, I can manage all my scripts from the same directory but still make some of them publicly available since /usr/local/bin is added to $PATH.

Backup or Sync Remote Files Using rsync

I wrote a shell script the other day to sync remote files using rsync. Thought I’d share it since it took me some time to get it exactly how I wanted.

rsync -rtvP --delete --include=$PATTERN* --exclude=* -e "ssh -i $SSH_KEY -p $SSH_PORT" $USERNAME@$DOMAIN:$SERVER_PATH/ $BACKUP_PATH/ 2> $ERROR_LOG

Per the man page, rsync is:

a fast, versatile, remote (and local) file-copying tool

It can also synchronize folders, so it’s more than just a file copying tool like scp. Furthermore, rsync has a significant number of options, so the documentation is quite lengthy.

To explain the code snippet above, I’ll start with the options in order of use and why I used them. You’ll also notice that I used $VARIABLES throughout the script. The definitions of these variables (among a few others) were included in the original script, but their values were both private and irrelevant so I’ve simply excluded them.

-rtvP

The -r or --recursive option allows you to recurse folders and specify them as the source or destination. Don’t forget to add a trailing slash (/) to your path.

The -t or --times option preserves the modification times on files when transferred. It’s often appropriate and preferred to use the -a or --archive option which is the same as using -rlptgoD. These options combined will recurse, copy symlinks as symlinks, and preserve permissions, modification times, group, owner, device files and special files (respectively). Perfect for archiving, but not what I wanted at the time.

The -v or --verbose option just causes rsync to be more ‘chatty’ and tell you what it’s doing.

The -P option is the same as adding --partial --progress. In essence, rsync will keep partial files if the transfer is interrupted and tell you the progress of the file transfer via standard output (your terminal screen…unless you redirect it). I wanted both these options so I chose -P.

–delete

Delete any files from the destination that do NOT exist in the source. There are a variety of other delete options to pick from should you need them.

–include=$PATTERN* –exclude=*

The --include and --exclude options take patterns that are matched against files in the source. The source folder included a number of files; however, I only wanted files that matched a specific pattern. In this case, all the files I wanted were prepended with something like ‘backup’, so that’s the value I assigned to $PATTERN. The filenames also included variable data like a timestamp, so in addition to the prefix I used the wildcard (*) to match any suffix.

If I hadn’t added the --exclude option, I still would have transferred all the files from the source folder. --include only explicitly says what should be included. It is NOT exclusive. Thus, I added --exclude=* which matches all other files. These filter rules are executed in order and build on one another. Theoretically, you could use multiple --include and --exclude options as needed. man rsync for more info.

-e “ssh -i $SSH_KEY -p $SSH_PORT”

The -e or --rsh=COMMAND option allows you to specify what remote shell want to use. I believe ssh is the default on most distributions. However, I also wanted to specify the private key I would use to authenticate with the remote server and what port I would use. -e allows me to specify these configurations.

$USERNAME@$DOMAIN:$SERVER_PATH/

The source path. Since it’s on a remote host, I’ve specified credentials and the hostname. Notice the trailing slash for my folder.

$BACKUP_PATH/

The destination path. Notice the trailing slash for my folder.

2> $ERROR_LOG

I chose to redirect all errors from sterr to a specific document.

Final Thoughts

If you want to test the command to make sure it works, just add the --dry-run option. I highly recommend it.

I’d also recommend creating a shell script file where you can define all your variables. It makes your script more readable and easier to edit in the future. Then you can add the script to your personal bin of scripts.

Invocation Patterns in JavaScript

There are four different invocation patterns in JavaScript that determine what the hidden parameter this is bound too.

Method Invocation Pattern

A method is a function tied to a property on an object. For methods, this is bound to the object upon invocation. For example:

var person = {
    name: 'Calvin',
    age: 25,
    greet: function () {
        alert('My name is ' + this.name + '.');
    }
};
person.greet(); //My name is Calvin.

In this example, this is bound to the person object upon invoking greet because greet is a method of person.

Function Invocation Pattern

For functions that are not properties on objects, this is bound to the global object. This is not very intuitive and is often considered one of the ‘bad parts’ of JavaScript–a mistake in language design. Naturally, you’d think this would be bound to the parent function, and that would have been much more helpful. Regardless, most developers overcome this problem by assigning this to a variable in the parent function. For example:

// Add a new method to person
person.calculateAge = function (yearsFromNow) {
	var self = this;

	function yearsOld() {
		return self.age + yearsFromNow;
	}

	alert('I will be ' + yearsOld() + ' years old ' + yearsFromNow + ' years from now.');
}
person.calculateAge(10); //I will be 35 years old 10 years from now.

In this example, I maintain a reference to the context of this by assigning it to the variable self. At the time of assignment, this is bound to the person object. As a result, I can access the property age on the person object from within the yearsOld function. self and that are common names for variables that maintain the context of this.

What if I had used this instead of self?

person.calculateAgeWrong = function (yearsFromNow) {
	function yearsOld() {
		return this.age + yearsFromNow; //NaN
	}

	alert('I will be ' + yearsOld() + ' years old ' + yearsFromNow + ' years from now.');
}
person.calculateAgeWrong(10);

Constructor Invocation Pattern

In JavaScript, functions can be invoked with the new prefix similar to the way objects are constructed in other languages. When this happens, this is bound to the new object. In addition, the resulting object is created with a link to the hidden prototype property of the function. This is what makes JavaScript a prototypal inheritance language as opposed to a classical inheritance language. There are no classes, but objects can inherit properties from other objects.

Functions that are designed to be called with the new prefix are by definition constructors. These functions are distinguished from others by using PascalCase as opposed to camelCase.

var Person = function (name) {
	this.name = name;
};

Person.prototype.greet = function () {
	return this.name + ' says hi.';
};

alert(new Person('Calvin').greet()); //Calvin says hi.

Notice the greet function uses this to access the name property. this is bound to Person.

Apply Invocation Pattern

As a functional object-oriented language, JavaScript makes it possible for functions to have methods as well. The apply function is a method on the Function.prototype–the prototype for all JS functions. apply makes it possible to use one object’s method in the context of another. We can do so by supplying an array with the correct number arguments and and the object to which this will be bound, also known as the context. Therefore, apply can take two arguments: (1) a context for this and (2) an array of arguments that will be applied to the method at hand.

var calvin = new Person('Calvin');
var hobbes = {name: 'Hobbes'};
alert(calvin.greet.apply(hobbes)); //Hobbes says hi.

Even though hobbes does not have a greet method, we can still apply the greet method from calvin because hobbes has a name property. If hobbes didn’t have a name property, the invocation would fail. This example demonstrates the invocation of the apply function with only one argument. greet doesn’t have any parameters so we didn’t provide apply an array of arguments.

Let’s say we have a method greetFriends that takes two arguments–two objects with a name property.

Person.prototype.greetFriends = function (friendA, friendB) {
	return this.name + ' says hi to ' + friendA.name + ' and ' + friendB.name + '.';
};

var bill = {name: 'Bill Watterson'};

alert(calvin.greetFriends.apply(bill, [calvin, hobbes]));
//Bill says hi to Calvin and Hobbes.

In this example, we supply two arguments to the apply function: bill as the context for this and an array with our two person objects. calvin and hobbes become the parameters friendA and friendB in greetFriends.

What if we were to have a method with an unpredictable number of arguments?

Sometimes in a web app you want to make an asynchronous request to a web server, often to a web API to fetch or modify some data. Sometimes you have to make multiple web requests and you don’t know how many because it depends on dynamic user input. Furthermore, you may want to execute some additional code after all the web requests are complete, so you might use a library like jQuery or Q that has a deferral/promise implementation. If you were using jQuery, your code might look something like the following, but with real data and a real purpose, not just to print out numbers:

// example & real world = set variables
var num = Math.ceil(Math.random() * 10),
	delay = 0,
	deferreds = [],
	element = document.getElementById('counter');

// example = print number when deferred is resolved
// real world = make asynchronous GET, POST, PUT, PATCH or DELETE request
function defer() {
	delay += 1000;
	return $.Deferred(function (def) {
		setTimeout(function () {
			element.innerHTML = --num;
			def.resolve();
		}, delay);
	}).promise();
}

// example = execute a random number of deferreds
// real world = execute a number of aync requests based on user input
// both = hold promises in an array
for (var i = num; i > 0; i--) {
	deferreds.push(defer());
}

// example = start off the countdown
element.innerHTML = num;

// example & real world = apply promises--unknown number until runtime
$.when.apply($, deferreds)
	.always(function () {
		// example & real world = take action after all promises are resolved
		element.innerHTML = num + '...done.';
	});

Since this example uses jQuery, I created a JSFiddle you can run to see the result.

More JavaScript

Closure in JavaScript

Closure is one of those terms you hear thrown around a lot in JavaScript development, but it’s often misunderstood and mistaken for scope. Scope is related and plays an important role in closure, but is not the same thing.

Closure is when a function has access to its original context. Here’s the Mozilla Developer Network’s take on closure:

A closure is a special kind of object that combines two things: a function and the environment in which that function was created. The environment consists of any local variables that were in-scope at the time that the closure was created.

An example:

function speak() {
    var greeting = 'hi';
    function saySomething() {
        console.log(greeting);
    }
    saySomething();
}
speak(); //hi

In this example, saySomething is a closure–it is a function that has access to its original context. Put differently, it is a function AND the environment in which it was created because it can access greeting, a variable from the parent function’s scope. greeting is not part of saySomething‘s scope.

Another example:

function speak(name) {
    var greeting = 'hi';
    function saySomething() {
        console.log(name + ' says ' + greeting);
    }
    saySomething();
}
speak('billy'); //billy says hi

In this example, speak defines a variable AND takes an argument. saySomething is still a closure–it can reference variables and parameters that are part of its environment.

A common misconception about closure is that you have to return a function for a closure to exist. This is NOT true. However, let’s expand the existing example by returning the saySomething function instead of executing it:

function speak(name) {
    var greeting = 'hi';
    function saySomething() {
        console.log(name + ' says ' + greeting);
    }
    return saySomething;
}
var billySpeaks = speak('billy');
var nobodySpeaks = speak('nobody');
billySpeaks();   //billy says hi
nobodySpeaks();  //nobody says hi

You’d think name and greeting would only be accessible at the time of execution, but that’s obviously not the case. That’s because local variables and arguments that are in scope at the time a closure is created remain accessible–they are part of the environment.

In the preceding example, speak is a closure that consists of the parameter name, the local variable greeting and the function saySomething when it was created. Therefore, billySpeaks and nobodySpeaks have access to them after execution has finished.

References

More JavaScript