自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

JavaScript異步調(diào)用框架問題描述

開發(fā) 前端
本文描述了對JavaScript異步調(diào)用的需求,一些現(xiàn)存的問題以及背景介紹。在Ajax應(yīng)用中,調(diào)用XMLHttpRequest是很常見的情況。然而在單線程的JavaScript編程中,XHR異步調(diào)用的代碼風(fēng)格實在是與一般的JavaScript代碼格格不入。

問題

在Ajax應(yīng)用中,調(diào)用XMLHttpRequest是很常見的情況。特別是以客戶端為中心的Ajax應(yīng)用,各種需要從服務(wù)器端獲取數(shù)據(jù)的操作都通過XHR異步調(diào)用完成。然而在單線程的JavaScript編程中,XHR異步調(diào)用的代碼風(fēng)格實在是與一般的JavaScript代碼格格不入。這樣就產(chǎn)生了對JavaScript異步調(diào)用的需求。

額外參數(shù)

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

function divide(operand1, operand2)

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

function divide(operand1, operand2, callback)

function divide(operand1, operand2, successCallback, failureCallback)

function divide(operand1, operand2, options)

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

可傳遞性

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

function calculate(operand1, operand2, operator)

這個calculate函數(shù)根據(jù)operator參數(shù)來調(diào)用內(nèi)部的plus, subtract, multiply, divide函數(shù)。然而,因為divide函數(shù)變成了異步函數(shù),所以整個calculate函數(shù)不得不也轉(zhuǎn)變?yōu)楫惒胶瘮?shù):

function calculate(operand1, operand2, operator, callback)

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

同步并存

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

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

calculate(operand1, operand2, operator, callback);

next();

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

如果calculate的實現(xiàn)是,當(dāng)不需要進行異步操作時,直接調(diào)用callback。那么,在執(zhí)行加減乘法時callback會在next之前被調(diào)用;在執(zhí)行除法時next會在callback之前調(diào)用。

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

然而后面一種做法依賴于成本較高的實現(xiàn)方式,開發(fā)者一個不小心(或者擺明偷懶)就會漏掉setTimeout,導(dǎo)致函數(shù)調(diào)用順序變得不確定,所以我們會希望這是框架幫助實現(xiàn)的功能,在使用框架時無法把這繞過。這些都指向?qū)avaScript異步調(diào)用的需求。

場景

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

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

◆用戶對象未緩存

◆異步讀取用戶信息

◆用戶對象已緩存

◆用戶是好友(信息更新會由服務(wù)器端推送)

◆同步讀取用戶信息

◆用戶不是好友(信息更新需要由客戶端拉?。?/P>

◆可以接受緩存信息

◆同步讀取用戶信息

◆必須獲取最新信息

◆異步讀取用戶信息

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

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

【編輯推薦】

  1. 淺談如何用Javascript+VML實現(xiàn)流程設(shè)計器
  2. 常用的JavaScript驗證正則表達式
  3. 給JavaScript初學(xué)者的24個小竅門
  4. JavaScript中關(guān)于Cookie的詳細(xì)介紹
  5. JavaScript中confirm,alert,prompt的用法
責(zé)任編輯:yangsai 來源: Cat in dotNET
相關(guān)推薦

2009-07-01 14:05:23

JavaScript異

2009-07-01 14:23:46

JavaScript異

2009-07-01 14:37:14

JavaScript異

2009-07-01 14:31:01

JavaScript異

2009-10-20 16:48:30

C#委托

2009-12-21 14:10:26

WCF異步調(diào)用

2009-11-09 10:50:30

WCF異步調(diào)用

2009-11-06 15:54:15

WCF異步調(diào)用

2009-08-21 11:24:16

C#異步調(diào)用

2010-02-22 13:28:05

WCF異步調(diào)用

2012-10-29 10:59:27

Windows 8

2009-12-07 14:26:47

WCF異步調(diào)用

2011-03-02 08:57:22

jQueryJavaScript

2009-12-07 14:35:42

WCF異步調(diào)用

2010-01-11 17:24:19

VB.NET異步調(diào)用

2021-03-29 09:26:44

SpringBoot異步調(diào)用@Async

2024-07-31 15:57:41

2024-10-15 10:28:43

2009-11-09 15:49:01

WCF異步調(diào)用

2009-08-21 11:02:55

C#異步調(diào)用
點贊
收藏

51CTO技術(shù)棧公眾號