同步:編程
我調用一個功能,該功能沒有結束前,我死等結果。promise
異步:異步
當一個異步過程調用發出後,調用者不能馬上獲得結果。該功能在完成後,經過狀態、通知和回調來通知調用者。socket
同步和非同步關注的是調用者是否等待等待調用結果。分佈式
舉個通俗的例子:
你打電話問書店老闆有沒有《分佈式系統》這本書,若是是同步通訊機制,書店老闆會說,你稍等,」我查一下",而後開始查啊查,等查好了(多是5秒,也多是一天)告訴你結果(返回結果)。
而異步通訊機制,書店老闆直接告訴你我查一下啊,查好了打電話給你,而後直接掛電話了(不返回結果)。而後查好了,他會主動打電話給你。在這裏老闆經過「回電」這種方式來回調。異步編程
阻塞:函數
調用我(函數),我(函數)沒有接收完數據或者沒有獲得結果以前,我不會返回。this
非阻塞:spa
調用我(函數),我(函數)當即返回通知調用者線程
以最經常使用的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一下老闆有沒有返回結果。
同步異步與阻塞非阻塞的關係:
異步調用的方式:
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; }