This is a VERY basic overview of how Asynchronous / Synchronous applications work within Unity, for more detailed examples please find the update execution order found here

How Synchronous code is executed in Unity

In a nut shell, synchronous executes in a linear way, meaning that it won’t execute the next line of code until its finished executing the code that its currently on.

As a practical example, take a look at the code below:

using UnityEngine;
using System.Collections;
public class Demonstration : MonoBehaviour {
	void Awake(){
		ThingsToDo();
	}
	void ThingsToDo(){
		Debug.Log("Awake");
		int numberOfTimes = 2;
		int i = 0;
		while(i++ < numberOfTimes){
			Debug.Log(string.Format("Number {0}",i));	
		}
		Debug.Log("Finish");
	}
}

This is a fairly simple script that simply print the following to the console in Unity.

	Awake
	Number 1
	Number 2
	Finish

As you can see, the code executes in order. If you were to edit the line numberOfTimes = 2; to numberOfTimes = 50; you would have 50 lines output instead of two. This code is Synchronous, as it will never hit the Finish statement before it ends the while loop.

What’s wrong with the Synchronous code before then?

To show you, I’ll use the code above. Change the line numberOfTimes = 2 to numberOfTimes = 2000. BEFORE YOU RUN THIS please realise that based on your computers processing speed this could take a few seconds .
Now run the code, you’ll notice that your Unity Editor freezes. This is because your script is holding onto the execution of its while loop letting the application move onto other code.

How to make your code Asynchronous in Unity?

To program Asynchronously in Unity, they have a system known as Co-routines. Co-routines allow for scripts to be executed over multiple frames instead of making the whole program wait for the script. In order to do this, please look at the code below:
For the sake of clarity I will not turn the Awake functions return type to IEnumerator because that can be confusing to new developers.

using UnityEngine;
using System.Collections;
public class Demonstration : MonoBehaviour {
	void Awake(){
		StartCoroutine(ThingsToDo()); // Changed
	}
	IEnumerator ThingsToDo(){ // Changed
		Debug.Log("Awake");
		int numberOfTimes = 2;
		int i = 0;
		while(i++ < numberOfTimes){
			Debug.Log(string.Format("Number {0}",i));	
			<strong>yield return 0;</strong>
		}
		yield return 0; // Changed
		Debug.Log("Finish");
	}
}

How does it work?

The StartCoroutine function, tells Unity to execute a function asynchronously, it accepts an IEnumerator function as an argument or a string (with the same name as the function you want to call). If you try to call the ThingsToDo() function directly, it will fail silently, so be sure to use StartCoroutine to call it!
As for the ThingsToDo function, I’ve changed its return type from void to IEnumerator, this is in order to access the yield statement which is crucial to making the function Asynchronous.

The yield return 0; statement tells Unity that it has finished executing for this frame and allows it to execute other code. The next frame it will pick up where it left off (in this instance in the middle of the loop). For more information on how Co-routines please find the Unity documentation about it.

Practical uses

Obviously asynchronous code has its flaws too, from what I can tell it imposes some overhead for each co-routine that is executing each frame. Mostly co-routines are used to load heavy data-sets (like XML based information) or to allow the program to wait for a few seconds before it executes something without making the rest of the application freeze up or crash due to a time-out.
Footnote: Typing asynchronous / synchronous over and over is actually quite difficult!