变态重口极致另类在线-波多久久夜色精品国产-波多野结衣在线观看一区-波多野结衣在线观看一区二区-污污的网站免费阅读-污污视频网址

當前位置:首頁文章首頁 IT學院 IT技術

Javascript的回調機制的經典教程

作者:  來源:  發布時間:2011-6-6 10:17:59  點擊:

  由于其運行環境的特殊性,Javascript大量使用異步的通信機制,凡是涉及到網絡調用和事件機制的代碼都會涉及。在異步通信的環境下編碼經常會用到 回調函數。Javascript由于有函數式語言的一些特點使得它在Javascript里面實現回調函數非常的優雅和自然,包括函數作為一級的對象、匿 名函數、閉包機制等。但是要體會到個中的優雅,需要先融匯貫通這些機制。如果是初學者學習這些東西可能比有編程經驗的人少很多障礙,認為事情本來就該是這 個樣子。但是,對于長期使用過程式語言編碼(比如傳統的C/C++程序員),又沒有接觸過函數式語言的程序員來說,可能需要閱讀一道思維的小坎。這件事情 有時候會造成一定的困擾,因為“老手”程序員會想:畢竟我已經懂得一套能寫程序的方法,大家都說語言之間差別不重要,畢竟C++里面也有使用異步調用的時 候,主要注意一下語法的區別就好了。所以最終就變成了使用Javascript來模仿別的過程式語言,這樣的結果最終很有可能是寫出很別扭的程序給自己添 堵。本文嘗試用幾個例子說明異步通信的環境用Javascript寫回調函數很使用類似C語言寫回調函數的區別,以及為什么Javascript原生要更 適合做這件事情。(簡單起見,下面例子中的代碼均為偽代碼,并不一定嚴格符合C/C++或者Javascript的語法,但是筆者盡量寫得與語法要求接 近。)

  

  我們首先從C/C++的同步調用開始,假設我們要寫一個函數,向遠方的服務器發送一個字符串形式得命令,并且從服務器得到一個字符串作為響應。例1就展示了使用C語言在同步同步通信的機制下代碼的樣子。

  

  例1 使用C語言的編碼方式實現調用訪問遠程的接口

  view plaincopy to clipboardprint?

  01.//{{{get_data_v1

  02.int get_data_v1()

  03.{

  04. // 準備數據

  05. char bufCmd[]="cmd=1001&uin=123456?m=abc";

  06. char bufRcv[4096];

  07. // 建立連接

  08. socket s = new Socket();

  09. connnect(s, ip, port);

  10. // 發送數據

  11. send(s, bufCmd);

  12. // 接收數據

  13. recv(s, bufRcv);

  14. // 處理結果

  15. use(bufRcv);

  16. return 0;

  17.}

  18.//}}}

  在 例1中,get_data_v1執行了準備數據、創建了socket、建立連接、發送請求、接收響應并最終使用use函數處理接收到的數據,一切都顯得很 自然。為了方便說明問題,我們將這個通信的過程封裝一下,將整個建立連接并收發包的過程封裝成一個叫send_and_recv的函數。

  

  例2 將通信過程封裝成獨立的函數,簡化業務流程代碼

  view plaincopy to clipboardprint?

  01.//{{{get_data_v2

  02.// 發包收包的過程

  03.int send_and_recv(struct addr, char* bufCmd, char* bufRcv)

  04.{

  05. socket s = new Socket();

  06. connnect(s, addr.ip, addr.port);

  07. send(s, bufCmd);

  08. recv(s, bufRcv);

  09.}

  10.// 原來的業務流程

  11.int get_data_v2()

  12.{

  13. // 準備數據

  14. char bufCmd[]="cmd=1001&uin=123456?m=abc";

  15. char bufRecv[4096];

  16. // 通信,收發數據

  17. // addr={ip, port}

  18. send_and_recv(addr, bufCmd, bufRcv);

  19. // 處理結果

  20. use(bufRcv);

  21. return 0;

  22.}

  23.//}}}

  例 2和例1很類似,不過是對通信過程進行封裝了,并且ip-port對也變成了一個叫addr的地址結構體。改動以后處理過程變得更簡單,剩下準備數據、通 信和處理結果三步。現在,我們開始進入正題,現在我們假設這個通信過程變成異步的,它接收一個回調函數用于處理取得的數據。如例3所示。

  

  例3 將通信過程變成異步調用

  view plaincopy to clipboardprint?

  01.//{{{get_data_v3

  02.// 變成異步調用以后,原來的調用過程分成了兩段

  03.// 前半段組裝參數調用發包過程

  04.// 后半段處理返

  05.// 這里假設send_and_recv是一個異步的網絡通信函數

  06.void get_data_v3()

  07.{

  08. char bufCmd[]="cmd=1001&uin=123456?m=abc";

  09. char bufRcv[4096];

  10. send_and_recv_async(addr, bufCmd, bufRcv, callback);

  11.} // end of get_data_v3

  12.// 回調函數的定義

  13.int callback(char* bufRcv) {

  14. // 處理接收都的數據

  15. use(bufRcv);

  16. return 0;

  17.}

  18.//}}}

  在 例3中,假設使用了一個異步的通信過程send_and_recv_async,最后一個參數callback是一個回調函數指針。然后,當接收到響應以 后,send_and_recv_async會調用callback并傳入接收到的數據。相比例2,這個get_data的過程被異步通信過程一分為二: 前半段為準備請求,后半段是處理結果。事實上,對將同步通信方式變成異步以后,都會涉及到將原來完整處理過程一分為二的問題。在兩段程序沒有什么相互依賴 的情況下,這樣的分解不會造成什么問題。但是,如果處理結果的過程依賴于一些外部參數,那么情況就會變得很復雜。我們先來看看在同步通信的情況下,程序的 樣子,見例4。

  

  例4 假設處理結果的時候依賴外部參數

  view plaincopy to clipboardprint?

  01.//{{{get_data_v4

  02.// 這里原來的業務流程需要外部傳進來的兩個參數(a,b)來決定如何處理結果

  03.int get_data_v4(int a, int b)

  04.{

  05. char bufCmd[]="cmd=1001&uin=123456?m=abc";

  06. char bufRcv[4096];

  07. send_and_recv(addr, bufCmd, bufRcv);

  08. // 處理過程依賴于外部傳進來的參數a和b

  09. use(bufRcv, a, b);

  10. return 0;

  11.}

  12.//}}}

  在例4中,我們的結果處理過程use依賴于傳入的兩個參數a和b。現在我們來看看例4的程序如果使用異步通信會怎樣,見例5。

  

  例5 加上參數依賴后再變成異步調用

  view plaincopy to clipboardprint?

  01.// 版本a

  02.//{{{get_data_v5

  03.// 需要參數的異步調用需要將參數透傳到后半段的回調函數中

  04.void get_data_v5a(int a, int b)

  05.{

  06. char bufCmd[]="cmd=1001&uin=123456?m=abc";

  07. char bufRcv[4096];

  08. send_and_recv_async(addr, bufCmd, bufRcv, callbacka, a, b);

  09.} // end of get_data_v5a

  10.// 回調函數的定義

  11.int callbacka(char* bufRcv, int a, int b) {

  12. use(bufRcv, a, b);

  13. return 0;

  14.}

  15.// 版本b

  16.int g_a;

  17.int g_b;

  18.void get_data_v5b(int a, int b)

  19.{

  20. g_a = a;

  21. g_b = b;

  22. char bufCmd[]="cmd=1001&uin=123456?m=abc";

  23. char bufRcv[4096];

  24. send_and_recv_async(addr, bufCmd, bufRcv, callbackb);

  25.} // end of get_data_v5b

  26.// 回調函數的定義

  27.int callbacka(char* bufRcv, int a, int b) {

  28.int callbackb(char* bufRcv) {

  29. use(bufRcv, g_a, g_b);

文章評論

軟件按字母排列: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
主站蜘蛛池模板: 欧美黑人粗暴另类多交 | 欧美日韩国产乱了伦 | 亚洲欧美h | 两个人免费视频www 两个人看的www中文字幕 | 日本欧美强乱视频在线 | 欧美亚洲风情 | 免费在线观看黄网站 | 日本黄色www | 一本大道香蕉大vr在线吗视频 | 中文字幕一精品亚洲无线一区 | 免费狼人久久香蕉网 | 开心久久激情 | 国产大片免费看 | 欧美vs日韩vs国产在线观看 | 黄色片在线免费 | www.五月婷婷.com | 一级片中国 | 免费a级毛片在线播放 | 国产综合免费视频 | 亚州国产 | 欧美在线看欧美高清视频免费 | 日韩在线你懂的 | 六月丁香激情 | 三级全黄视频 | 男人把女人下面桶爽的视频 | 日韩不卡一区 | 日韩精品欧美在线 | 大学生一级毛片全黄真人 | 天堂在线观看视频观看www | 国产精品成人在线 | 午夜免费影院 | 国产麻豆永久视频 | 一本大道香蕉大vr在线吗视频 | 亚洲日本视频在线 | 伦理片在线观看网站资源 | 国外性xxxnxxxf视频 | 成人狠狠色综合 | 精品久草 | 国产香港一级毛片在线看 | 国产色视频网站 | 中文字幕在线观看网站 |