When teaching people to code, most early instructional material focuses heavily on code that executes straight from top to bottom. This comes about naturally, beginning with lower levels of complexity, allowing visual arrangements to help reinforce the sequence of code execution. There comes a point however as complexity increases, when programs begin to look a little less linear. It starts with functions calling other functions and expands to folders full of files all interacting with each other. Eventually you start sending requests to servers over a network (the world wide web even), which may respond, may give you an error, and may not respond at all.
Above is a textbook example. Because the $.get function is an asynchronous call to a web server, the GET request will be fired, but then your program will run the later lines of code before the response makes it’s way back to you. In this instance you would typically see “Script” logged before “Java”.
This asynchronous $.get request and many other asynch functions return some form of deferred object, often behaving with a Promise interface. The primary implication for us today is that you can append code that you want to execute after the request completes into a callback function.
This ensures that “Script” is not logged until the GET request completes and logs “Java”. There is a lot more capability to Promises than this. Error handling and chaining multiple callbacks open the door to powerful features when constructed well. In short deferred objects offer another dimension of flow control. Becoming more familiar with using these objects not only helps you to write code more effectively, but can open the door to some more advanced functionality.