-
jQuery的異步設計邏輯也確實很復雜,需要思維跳轉很活躍,某一個時間在這里,下一個片段又要另一個地方去了,不是按照同步代碼這樣執(zhí)行的。需要大家有一定的空間跳躍力了。
查看全部 -
when方法的設計。我們通過模擬的代碼,可以很簡單的分析整個流程:
? 1. 傳遞了多個異步對象,然后遍歷每個異步對象給每一個對象綁定done、fail、progess方法,無非就是監(jiān)聽每一個異步的狀態(tài)(成功,失?。?,如果是完成了自然會激活done方法。
? 2. updateFunc是監(jiān)聽方法,通過判斷異步對象執(zhí)行的次數來決定是不是已經完成了所有的處理或者是失敗處理
? 3. 因為when也要形成異步操作,比如when().done(),所以內部必須新建一個jQuery.Deferred()對象,用來給后面鏈式調用。
? 4. 此刻監(jiān)聽所有異步對象(d1,d2...)的updateFunc的處理都完畢了,會給一個正確的通知給when后面的done方法,因為done是通過第三步jQuery.Deferred()創(chuàng)建的,所以此時就需要發(fā)送消息到這個上面,即:
deferred.resolveWith(contexts,?values);
? 5. 內部的jQuery.Deferred()因為外部綁定了when().done(),所以done自然就收到了updateFunc給的消息了,可以繼續(xù)之后的操作了。
查看全部 -
Deferred的then處理:
我們可以把每一次的then操作,當做是創(chuàng)建一個新的deferred對象,那么每一個對象都夠保存自己的狀態(tài)與各自的處理方法。通過一個辦法把所有的對象操作都串聯(lián)起來,這就是then或者pipe管道設計的核心思路了。
其實在內部創(chuàng)建了一個新的Deferred對象,不過這里的不同是通過傳遞一個回調函數,參數是newDefer,其實Deferred內部就是為了改變下上下文this為deferred,然后傳遞deferred給這個回調函數了,所以newDefer就指向內部的deferred對象了。
如果then返回的是一個promise對象(ajax)的時候,也可以直接處理了
if?(returned?&&?jQuery.isFunction(returned.promise))?{ ??returned.promise() ????.done(newDefer.resolve) ????.fail(newDefer.reject) ????.progress(newDefer.notify);
查看全部 -
Deferred源碼剖析
Deferred自身則圍繞這三組數據進行更高層次的抽象
1、觸發(fā)回調函數列表執(zhí)行(函數名)
2、添加回調函數(函數名)
3、回調函數列表(jQuery.Callbacks對象)
4、Deferred最終狀態(tài)(第三組數據除外)
var?tuples?=?[ ??//?action,?add?listener,?listener?list,?final?state ??["resolve",?"done",?jQuery.Callbacks("once?memory"),?"resolved"], ??["reject",?"fail",?jQuery.Callbacks("once?memory"),?"rejected"], ??["notify",?"progress",?jQuery.Callbacks("memory")] ]
通過stateString有值這個條件,預先向doneList,failList中的list添加三個回調函數,分別是:
doneList?:?[changeState,?failList.disable,?processList.lock] failList?:?[changeState,?doneList.disable,?processList.lock]
1、changeState 改變狀態(tài)的匿名函數,deferred的狀態(tài),分為三種:pending(初始狀態(tài)), resolved(解決狀態(tài)), rejected(拒絕狀態(tài));
2、不論deferred對象最終是resolve(還是reject),在首先改變對象狀態(tài)之后,都會disable另一個函數列表failList(或者doneList);
3、然后lock processList保持其狀態(tài),最后執(zhí)行剩下的之前done(或者fail)進來的回調函數。
4、所以第一步最終都是圍繞這add方法:done/fail/是list.add也就是callbacks.add,將回調函數存入回調對象中。
查看全部 -
沒有使用promise的情況下,實現了類似promise的功能,666!
查看全部 -
觀察者模式中的訂閱方法:
?Done (操作完成)
?Fail (操作失敗)
?Progress (操作進行中觀察中模式中的發(fā)布方法:
?resolve(解決)
?reject(拒絕)
?notify(通知)而且還提供了可以定義運行時的this對象的fire,fireWith,所以擴展了3個可以定義上下文的的接口:
resolveWith
rejectWith
notifyWith查看全部 -
“管道”風格
CommonJS Promise/A 標準這樣定義的,promise對象上的then方法負責添加針對已完成和拒絕狀態(tài)下的處理函數。then方法會返回另一個promise對象,這樣可以形成“管道”風格。
查看全部 -
promise背后的思想:不是執(zhí)行一個方法,然后阻塞應用程序等待結果返回,而是返回一個promise對象來滿足未來值,即承諾、許諾完成當前操作后,會執(zhí)行預先設定的后續(xù)操作
查看全部 -
querySelector的IE8兼容處理:在上下文調用的context元素上指定一個id,通過這個限制范圍,這個方法用的非常廣泛
具體過程:
1、關鍵是給context設置一個id,所以上下文content,就會存在這個id限制范圍
2、拼接出查詢的選擇器,附上這個ID前綴
newSelector:?"[id='sizzle-1405486760710']?div[class='text']"
3、查詢
newContext.querySelectorAll(?newSelector?)
4、因為強制加了ID,所以需要刪除
context.removeAttribute("id");
查看全部 -
正則表達式中【$&】的意思
$1、$2、...、$99 ? ?與 regexp 中的第 1 到第 99 個子表達式相匹配的文本。 ? ?
$& ? ?與 regexp 相匹配的子串。 ? ?
$` ? ?位于匹配子串左側的文本。 ? ?
$' ? ?位于匹配子串右側的文本。 ? ?
$$ ? ?直接量符號。 ? ?
查看全部 -
document.querySelectorAll?與?element.querySelectorAll區(qū)別:
1、element.querySelectorAll 在文檔內找全部符合選擇器描述的節(jié)點包括Element本身
2、選擇上下文是在aaRoot里面,選擇器是.aaron就父節(jié)點,理論是找不到對應的節(jié)點的。但是結果跟document調用如出一轍,所以此時node ele類似document了。
3、可能的查找機制是這樣的:首先在document的范圍內進行查找所有滿足選擇器條件的元素,在上面這段代碼中,我們的選擇器是.aaron span,就是所有的直接父元素類名為.aaron的元素。然后,再看哪些元素是調用querySelector/querySelectorAll的元素的子元素,這些元素將會被返回。
查看全部 -
IE兼容問題:
1、關于getElementById,在IE8之前是不區(qū)分大小寫的。除此之外,IE8之前在針對表單的處理時候,表單的name與id重名,并且name在id之前,則會返回表單元素
2、關于getElementsByTagName,如果選擇器是通配符"*"的話,IE6-8會混雜注釋節(jié)點,所以針對如果是tag為*的情況,我們需要做一個兼容的處理
3、關于getElementsByClassName,IE卻并不支持這個方法,我們不得不專門為IE實現這么一個函數
查看全部 -
為什么排版引擎解析 CSS 選擇器時一定要從右往左析?
1、要知道DOM樹是一個什么樣的結構,一個元素可能有若干子元素,如果每一個都去判斷一下顯然性能太差。而一個子元素只有一個父元素,所以找起來非常方便。你可以看看CSS的選擇器的設計,完全是為了優(yōu)化從子元素找父元素而決定的。
2、打個比如?p span.showing。你認為從一個p元素下面找到所有的span元素并判斷是否有class showing快,還是找到所有的span元素判斷是否有class showing并且包括一個p父元素快 ?
查看全部 -
CSS選擇器分類:
群組選擇器:逗號“,”
簡單選擇器:ID、標簽、類、屬性、通配符
關系選擇器:孩子、后代、相鄰、兄弟
偽類選擇器:動作偽類、目標偽類、語言偽類、狀態(tài)偽類、結構偽類、取反偽類偽類細分:
基本篩選器: eq get first lang It not odd root...
內容篩選器: contains empty has parent...
可見篩選器: hidden visible
子元素篩選器: first-child nth-child only-child...
表單: bottom checkbox foucs input text...查看全部 -
Deferred 提供了一個抽象的非阻塞的解決方案(如異步請求的響應),它創(chuàng)建一個promise對象,其目的是在未來某個時間點返回一個響應。簡單來說就是一個異步/同步回調函數的處理方案。
一:Ajax的改造
$.ajax({ ??url:?"aaron.html", ??success:?function(){ ?????alert("成功!"); ??}, ??error:function(){ ????alert("失?。?); ??} }) $.ajax("aaron.html")?//?返回不再是xhr對象,而是經過包裝的Deferred對象 .done(function(){?alert("成功");?}) .fail(function(){?alert("出錯");?});
二:提供一種方法來執(zhí)行一個或多個對象的回調函數
$.when($.ajax("a1.html"),?$.ajax("a2.html")) .done(function(){?alert('2次回調都正確返回了')?}) .fail(function(){?alert('出錯了');?});
三:可以混入任意的對象接口中
jQuery的Deferred最好用的地方,就是模塊化程度非常高,可以任意配合使用:
把需要處理的異步操作,用Deferred對象給包裝一下,然后通過when方法收集異步的操作
function?task(name)?{ ??var?dtd?=?$.Deferred(); ??setTimeout(function()?{ ????dtd.resolve(name) ??},?1000) ??return?dtd; } $.when(task('任務一'),?task('任務二')).done(function()?{ ??alert('成功') })
查看全部
舉報