同步:
我調用一個功能,該功能沒有結束前,我死等結果。
異步:
當一個異步過程調用發出后,調用者不能立刻得到結果。該功能在完成后,通過狀態、通知和回調來通知調用者。
同步和非同步關注的是調用者是否等待等待調用結果。
舉個通俗的例子:
你打電話問書店老板有沒有《分布式系統》這本書,如果是同步通信機制,書店老板會說,你稍等,”我查一下",然后開始查啊查,等查好了(可能是5秒,也可能是一天)告訴你結果(返回結果)。
而異步通信機制,書店老板直接告訴你我查一下啊,查好了打電話給你,然后直接掛電話了(不返回結果)。然后查好了,他會主動打電話給你。在這里老板通過“回電”這種方式來回調。
阻塞:
調用我(函數),我(函數)沒有接收完數據或者沒有得到結果之前,我不會返回。
非阻塞:
調用我(函數),我(函數)立即返回通知調用者
以最常用的send和recv兩個函數為例
比如你調用send函數發送一定的Byte,在系統內部send做的工作其實只是把數據傳輸(Copy)到TCP/IP協議棧的輸出緩沖區,它執行成功並不代表數據已經成功的發送出去了,如果TCP/IP協議棧沒有足夠的可用緩沖區來保存你Copy過來的數據的話...這時候就體現出阻塞和非阻塞的不同之處了:對於阻塞模式的socket send函數將不返回直到系統緩沖區有足夠的空間把你要發送的數據Copy過去以后才返回,而對於非阻塞的socket來說send會立即返回WSAEWOULDDBLOCK告訴調用者說:"發送操作被阻塞了!!!你想辦法處理吧..."
對於recv函數,同樣道理,對於阻塞模式的socket來說如果TCP/IP協議棧的接收緩沖區沒有通知一個結果給它它就一直不返回:耗費着系統資源....對於非阻塞模式的socket該函數會馬上返回,然后告訴你:WSAEWOULDDBLOCK---"現在沒有數據,回頭再來看看"
阻塞I/O模型:

非阻塞I/O模型:

阻塞和非阻塞關注的是調用者在等待調用結果時的狀態。
還是上面的例子,
你打電話問書店老板有沒有《分布式系統》這本書,你如果是阻塞式調用,你會一直把自己“掛起”,直到得到這本書有沒有的結果,如果是非阻塞式調用,你不管老板有沒有告訴你,你自己先一邊去玩了, 當然你也要偶爾過幾分鍾check一下老板有沒有返回結果。
同步異步與阻塞非阻塞的關系:
- 在處理 IO 的時候,阻塞和非阻塞都是同步 IO。socket接收數據的recv函數,如果沒有數據的情況下調用該函數,則當前線程就會被掛起,直到有數據為止(同步&阻塞);CSocket中調用Receive函數,如果緩沖區中沒有數據,這個函數就會一直等待,直到有數據才返回,而此時,當前線程還會繼續處理各種各樣的消息(同步&非阻塞)。
- 只有使用了特殊的 API 才是異步 IO。

異步調用的方式:
function lightUp(A, callback){
callback();
A.lightUp();
}
function callback(){
B.lightUp();
}
var temp = false;
while(!temp){
temp = wait(A.lightUp());
}
B.lightUp();
function AlightUp(){
this.trigger('done');
this.do();
}
function BlightUp(){
this.do();
}
AlightUp.on('done',BlightUp);
jQuery.subscribe("done", f2);
function f1(){
setTimeout(function () {
// f1的任務代碼
jQuery.publish("done");
}, 1000);
}
jQuery.unsubscribe("done", f2);
f1().then(f2);
function f1(){
var dfd = $.Deferred();
setTimeout(function () {
// f1的任務代碼
dfd.resolve();
}, 500);
return dfd.promise;
}

