<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      代碼改變世界

      寫個 JavaScript 異步調用框架 (Part 1 - 問題 & 場景)

      2009-05-06 00:18  Cat Chen  閱讀(5372)  評論(6)    收藏  舉報

      問題

      在Ajax應用中,調用XMLHttpRequest是很常見的情況。特別是以客戶端為中心的Ajax應用,各種需要從服務器端獲取數據的操作都通過XHR異步調用完成。然而在單線程的JavaScript編程中,XHR異步調用的代碼風格實在是與一般的JavaScript代碼格格不入。

      額外參數

      考慮一個除法函數,如果它是純客戶端的同步函數,那么簽名會是這樣的:

      function divide(operand1, operand2)

      然而假設我們對客戶端除法的精度不滿意,于是把除法轉移到服務器端來執行,那么它是個需要調用XHR的異步函數,簽名也就可能會是以下幾種之一:

      function divide(operand1, operand2, callback)
      function divide(operand1, operand2, successCallback, failureCallback)
      function divide(operand1, operand2, options)

      我們必須在簽名中引入新的參數來傳遞回調函數,不能選擇讓函數變成阻塞式的同步調用。

      可傳遞性

      不僅僅直接操作XHR的函數需要引入新的參數,這種復雜性還會順著調用棧向外傳遞。例如說,我們對加減乘除四則運算作了封裝,只向外暴露一個運算接口:

      function calculate(operand1, operand2, operator)

      這個calculate函數根據operator參數來調用內部的plus, subtract, multiply, divide函數。然而,因為divide函數變成了異步函數,所以整個calculate函數不得不也轉變為異步函數:

      function calculate(operand1, operand2, operator, callback)

      同時,在調用棧之上凡是需要調用到calculate的函數,都必須變成異步的,除非它并不需要向上一級調用函數返回結果。

      同步并存

      盡管calculate函數變成了一個異步函數,它所調用的plus, subtract, multiply函數還是同步函數,只有調用divide時是異步的,這時候calculate就是一個異步同步并存函數。

      這會帶來什么問題?calculate的調用者看到函數簽名自然會認為calculate是個異步函數,因為它需要傳遞回調函數,然而calculate的執行方式卻是不確定的。考慮如下調用:

      calculate(operand1, operand2, operator, callback);
      next();

      這里涉及到callback和next兩個函數,它們哪個先執行哪個后執行是不確定的,或者說是依賴于calculate具體實現的。

      如果calculate的實現是,當不需要進行異步操作時,直接調用callback。那么,在執行加減乘法時callback會在next之前被調用;在執行除法時next會在callback之前調用。

      如果我們不喜歡這種不確定性,我們可以改變一下calculate的實現,把同步調用也都改為setTimeout形式的,這樣在任何情況下next都一定會在callback之前被調用。

      然而后面一種做法依賴于成本較高的實現方式,開發者一個不小心(或者擺明偷懶)就會漏掉setTimeout,導致函數調用順序變得不確定,所以我們會希望這是框架幫助實現的功能,在使用框架時無法把這繞過。

      場景

      在這里,我舉一個關于上述問題的具體應用場景。(為簡化問題,描述已略作修改,與實際應用并不一致。)

      百度Hi網頁版里面,我們會在客戶端保存一個用戶對象列表,在打開和這個用戶的聊天窗口時,我們需要從中讀取這個用戶的信息。這個操作就涉及很多可能同步又可能異步的分支:

      • 用戶對象未緩存
        • 異步讀取用戶信息
      • 用戶對象已緩存
        • 用戶是好友(信息更新會由服務器端推送)
          • 同步讀取用戶信息
        • 用戶不是好友(信息更新需要由客戶端拉取)
          • 可以接受緩存信息
            • 同步讀取用戶信息
          • 必須獲取最新信息
            • 異步讀取用戶信息

      可以看到,分支的結果最終既有同步的,也有異步的。并且這些分支還不是在一個函數里完成,而是在幾個函數里實現。也就是說,按照傳統的模式,這些函數一部分是同步的,一部分是異步的,由于異步的傳遞性,最終調用棧頂層的函數都是異步的。

      為了解決這個問題,我們需要寫一個異步調用框架,用一種統一的方式來進行調用,把同步和異步調用都合并為一種返回方式。

      具體的解決方案會在下一篇文章中給出,如果你不希望錯過的話,歡迎訂閱我的博客:

      主站蜘蛛池模板: 国产黄色精品一区二区三区| 国产免费高清69式视频在线观看| 国产精品一区二区三区专区| 四虎库影成人在线播放| 中文字幕人妻中文AV不卡专区| 精品国产熟女一区二区三区| jk白丝喷浆| 在线观看免费人成视频色| 无码国内精品久久人妻蜜桃| 国产无遮挡又黄又爽高潮| 亚洲色偷偷偷网站色偷一区| 亚洲av免费成人在线| 国内精品无码一区二区三区| 国产精品高清一区二区三区| 诱人的老师hd中文字幕| 国产目拍亚洲精品二区| 日韩女同一区二区三区久久| 亚洲永久视频| 人妻少妇精品视频专区| 国产精品自拍自在线播放| 国产成人亚洲无码淙合青草| 四虎影视4hu4虎成人| 亚洲欧美日韩成人综合一区| 青草内射中出高潮| 精品视频福利| 狠狠色噜噜狠狠狠狠色综合久| 丁香五月婷激情综合第九色| 国产自产视频一区二区三区| 亚洲精品一区二区三区大桥未久| 午夜福利电影| 日韩精品国产中文字幕| 调兵山市| 久久a级片| 日本另类αv欧美另类aⅴ| 国产精品福利自产拍在线观看| 亚洲av鲁丝一区二区三区黄| 亚洲日韩欧洲乱码av夜夜摸| 高中女无套中出17p| 好先生在线观看免费播放 | 精品日本免费一区二区三区| 日本亚洲一区二区精品|