聊聊同步、異步和回調

12 評論 22469 瀏覽 174 收藏 7 分鐘

有一天,你找到公司剛來的程序員小 T,跟他說:“我們要加個需求,你放下手里的事情優先支持,我會一直等你做完再離開”。小 T 微笑著答應了,眼角卻滑過一絲不易覺察的殺意。

切入正題。世界上的所有事情大致可以分為同步去做和異步去做兩種。你打電話去訂酒店,電話另一邊的工作人員需要查下他們的管理系統才能告訴你有沒有房間。這時候你有兩種選擇,一種是不掛電話一直等待,直到工作人員查到為止(可能幾分鐘也可能幾個小時,取決于他們的辦事效率),這就是同步的。另一種是工作人員問了你的聯系方式就掛斷了電話,等他們查到之后再通知你,這就是異步的,這時候你就可以干點其他事情,比如把機票也定了之類的。同步和異步的區別就在于,在下達了執行任務的命令后,是等到執行完成之后才能得到結果呢,還是馬上就知道了結果(盡管是不確定的答案)。

計算機世界也是如此。我們寫的代碼是交給 CPU 去執行的,在這個過程中經常面臨是讓 CPU 同步執行還是異步執行的選擇。比如我寫了一個 APP,它可以幫你下載網絡上的一個文件。當你輸入一個文件的網址,按下下載按鈕的一瞬間,CPU 就收到了一個下載文件的任務。我們先想象一下同步執行時什么情況。CPU 立刻停掉了手頭的事情,包括繪制界面、對用戶的點擊做出響應等等,傾盡全力去幫你下載文件。但是,這時候你會發現,你的屏幕再也沒有響應了,整個系統就像死了一樣(廢話,CPU 都被你的下載任務搶走了)。過幾秒鐘,如果是 Android 系統則會彈出一個下面圖 1 的提示,用戶非常感動,然后無情的卸載了這個 APP(尼瑪褲子都脫了,你讓我看這個)。同樣的情況異步執行要好很多。CPU 馬上告訴你任務已經被受理了,等下載完成我會通知你的。于是呢,屏幕照樣刷新,用戶點擊都能做出處理,就好像沒有下載過一樣。然而 CPU 并沒有閑著,它開啟了一個線程,專門處理這個下載任務(還記得之前講過的線程的概念嗎?不用擔心我們下面會詳細講)。過了幾個小時下載完了,你會收到一個通知,告訴你任務執行的結果(圖 2)。

2015-12-21-sync1

2015-12-21-sync2

一般情況下計算機通過多線程來實現同步,你可以把線程看做是富土康生產 iPhone 的一條生產線。它給生產一臺完整的 iPhone 提供了所有必須的資源:包括人力,原料,設計圖紙等等。生產任務來的時候,如果是同步的,那一條生產線就夠了,所有的小伙伴們蜂擁而上,不一會兒就搞定了。如果是異步的,那就必須新建一條生產線(好在 CPU 創建線程的成本并不高),分一部分資源到新的生產線上,這樣可以同時生產兩臺手機。那么生產線可以無限制增加嗎?答案是不行的。一是異步會面臨資源競爭的問題。比如說 8 條生產線都要組裝電池,但是電池原料只有 4 份,那么必然會存在其他 4 條生產線等待的其情況,如果資源競爭比較頻繁,甚至異步的執行效率要低于同步。二是異步會導致狀態難以管理。比如車間主任想要統計一共生產了多少 iPhone,就必須要詢問完所有生產線才能得出結論,而且這個詢問過程必須要停掉所有的生產線,同步來做。

講到這里,回調的概念呼之欲出。上面異步任務的整個過程是首先你要把自己的信息給異步任務執行者,等執行完成的時候,執行者可以通過這些信息找到你,并給你一個通知。把自己信息給別人的過程叫做注冊,別人找到你給你通知的過程就叫做回調。上面的例子,你把自己的聯系方式給了酒店工作人員叫做注冊,工作人員完成任務后聯系你叫做回調。但是回調的概念其實非常廣,這里可以抽象成先把要做的事情注冊給別人,等條件滿足的時候別人再回過頭來調用你的模型。程序上響應一個按鈕點擊之后要做的事情也是用回調來做的。程序員先把用戶點了按鈕要做的事情先寫好(比如要下載文件),注冊給系統。等用戶點擊到按鈕的時候,系統就會回調你下載文件的代碼。

回到開篇,了解了同步、異步以及回調之后,你會這樣跟小 T 說:” 我們要加個需求,你抽時間支持下,等你做完了記得通知我?!靶?T 欣然理接受,眼角閃過理解萬歲的淚光,回頭就把這事兒忘了。

本文來自微信公眾號“給產品經理講技術”(pm_teacher)

更多精彩內容,請關注人人都是產品經理微信公眾號或下載App
評論
評論請登錄
  1. 回頭就把這事兒忘了

    來自廣東 回復
  2. 哈哈哈最后一句,我看了寂寞

    回復
  3. “回頭就把這事兒忘了”你有你的回調,我有我的輪詢

    來自浙江 回復
  4. 【回頭就把這事兒忘了】是重點,圈起來要考的

    來自廣東 回復
  5. 仿佛在逛抖音。。。

    來自湖南 回復
  6. ?? 最后一句很是形象

    來自廣東 回復
  7. ?? 回頭就把這事兒忘了。。感覺小T附體

    來自河南 回復
  8. :mrgreen:

    來自江蘇 回復
  9. 哈哈哈哈哈哈哈 最后亮了~ ??

    來自浙江 回復
  10. 最后一句。。。 ??

    來自遼寧 回復
  11. 看到“回頭就把這事兒忘了”感覺到貌似白看了- –

    來自北京 回復
    1. 啊哈哈哈哈哈

      來自北京 回復