在日常瀏覽網(wǎng)頁(yè)的過(guò)程中,我們經(jīng)常會(huì)看到在使用chrome56以上版本訪問(wèn)一些涉及到用戶(hù)帳號(hào)、密碼之類(lèi)含有敏感信息的頁(yè)面時(shí),chrome瀏覽器的地址欄里會(huì)出現(xiàn)“不安全”提示,如下圖:

此時(shí),我們采取的做法通常是把該頁(yè)面開(kāi)啟https支持,通過(guò)https://yourdomain.com 來(lái)消除“不安全”提示,如下圖:

具體的開(kāi)啟https的過(guò)程,本文就不深入去介紹了。
于是在實(shí)際的應(yīng)用中,作為前端的我,噼里啪啦把頁(yè)面所有“http://”改成“//”,然后高呼一聲:大功告成,打完收工!
然鵝。。。打開(kāi)chrome控制臺(tái)一看,

chrome控制臺(tái)警告:Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check http://xhr.spec.whatwg.org/.

這是什么鬼?完成看不懂!?。?!此時(shí)度娘輕蔑地傳來(lái)一聲:叫你不好好讀書(shū),這句的意思是XMLHttpRequest同步請(qǐng)求占用了主線程,導(dǎo)致js進(jìn)程發(fā)生阻塞。
受內(nèi)傷的我于是高呼一聲度娘你牛逼之后,趕緊扒開(kāi)代碼一看,果然在一個(gè)組件里發(fā)現(xiàn)了幾個(gè)ajax是把a(bǔ)sync設(shè)置成了false的,意思是關(guān)閉了異步請(qǐng)求。那趕緊把a(bǔ)sync設(shè)為true唄,然后保存、刷新一看,咦,果然發(fā)現(xiàn)chrome的小嘆號(hào)消失了,一抹亮麗的綠色像春天的嫩芽一樣出現(xiàn)在chrome瀏覽器的頭上,

完美解決!!
正當(dāng)我洋洋得意再次刷新頁(yè)面的時(shí)候,突然網(wǎng)絡(luò)卡了一下,然后控制臺(tái)爆出了一條紅色的報(bào)錯(cuò)提示

趕緊查看剛才改動(dòng)的ajax,發(fā)現(xiàn)其中一個(gè)$.each(arr,fun)的arr參數(shù)依賴(lài)它上面的ajax返回的數(shù)據(jù),由于剛才把這個(gè)ajax的async改成了true異步請(qǐng)求數(shù)據(jù),$.each()執(zhí)行時(shí)arr還沒(méi)有值傳過(guò)來(lái),于是報(bào)錯(cuò)!很好,知道問(wèn)題在哪了,解決它易如反掌:把該each寫(xiě)到ajax的success回調(diào)函數(shù)里不就OK了嗎?但再仔細(xì)看看each的上下文,發(fā)現(xiàn)它必須呆在ajax的外面,不能直接寫(xiě)到success回調(diào)里,這就尷尬了,頓時(shí)傻眼。。。

于是我再次汗顏,怎樣解決上下文異步傳值的問(wèn)題????
功夫不負(fù)有錢(qián)人,通過(guò)度娘終于發(fā)現(xiàn)了“$.Deferred”這把殺豬刀。
上代碼:
var dtd = $.Deferred();
$.ajax({
url: url,
type: 'GET',
async:true,
dataType: 'json',
cache: false
}).done(function(res){
...
dtd.resolve(res);
}).fail(function(jqXHR, textStatus, errorThrown) {
...
dtd.reject(jqXHR, textStatus, errorThrown);
});
if($.isArray(dtd)) {
var arr = dtd;
$.each(arr, function(index, val){
...`` });
}
這樣通過(guò)Deferred作為管道,可以使因ajax若使用同步獲取數(shù)據(jù)模式會(huì)占用js主進(jìn)程導(dǎo)致chrome56以上會(huì)出現(xiàn)小嘆號(hào),若使用異步獲取數(shù)據(jù)模式會(huì)導(dǎo)致下一步的業(yè)務(wù)邏輯因不能及時(shí)取到返回值而出現(xiàn)報(bào)錯(cuò)這兩個(gè)矛盾的問(wèn)題得到解決。
【總結(jié)】在給頁(yè)面做https支持的時(shí)候,若遇到因ajax使用了同步請(qǐng)求而出現(xiàn)如上面的chrome瀏覽器出現(xiàn)小嘆號(hào)提示的時(shí)候,請(qǐng)使用異步請(qǐng)求來(lái)解除js主線程的占用,消除小嘆號(hào)。若業(yè)務(wù)邏輯需要必須使用同步請(qǐng)求,那么請(qǐng)嘗試使用ajax設(shè)置為異步請(qǐng)求然后用Deferred來(lái)承載返回值的方法。
此外,Deferred的使用場(chǎng)所還有:
Ajax(XMLHttpRequest)
Image Tag,Script Tag,iframe(原理類(lèi)似)
setTimeout/setInterval
CSS3 Transition/Animation
HTML5 Web Database
postMessage
Web Workers
Web Sockets
and more…