聊聊同步、異步和回調(diào)

12 評(píng)論 22507 瀏覽 174 收藏 7 分鐘

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

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

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

2015-12-21-sync1

2015-12-21-sync2

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

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

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

本文來自微信公眾號(hào)“給產(chǎn)品經(jīng)理講技術(shù)”(pm_teacher)

更多精彩內(nèi)容,請(qǐng)關(guān)注人人都是產(chǎn)品經(jīng)理微信公眾號(hào)或下載App
評(píng)論
評(píng)論請(qǐng)登錄
  1. 回頭就把這事兒忘了

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

    回復(fù)
  3. “回頭就把這事兒忘了”你有你的回調(diào),我有我的輪詢

    來自浙江 回復(fù)
  4. 【回頭就把這事兒忘了】是重點(diǎn),圈起來要考的

    來自廣東 回復(fù)
  5. 仿佛在逛抖音。。。

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

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

    來自河南 回復(fù)
  8. :mrgreen:

    來自江蘇 回復(fù)
  9. 哈哈哈哈哈哈哈 最后亮了~ ??

    來自浙江 回復(fù)
  10. 最后一句。。。 ??

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

    來自北京 回復(fù)
    1. 啊哈哈哈哈哈

      來自北京 回復(fù)