導航:首頁 > 編程語言 > js寫成非同步處理

js寫成非同步處理

發布時間:2023-06-02 21:32:19

js非同步問題怎麼解決

非同步載入又叫非阻塞載入,瀏覽器在下載執行js的同時,還會繼續進行後續頁面的處理。主要有三種方式。
方法一:也叫Script DOM Element
(function(){
var scriptEle = document.createElement("script");
scriptEle.type = "text/javasctipt";
scriptEle.async = true;
scriptEle.src = "http://cdn.bootcss.com/jquery/3.0.0-beta1/jquery.min.js";
var x = document.getElementsByTagName("head")[0];
x.insertBefore(scriptEle, x.firstChild);
})();

<async>屬性是HTML5中新增的非同步支持。此方法被稱為Script DOM Element 方法。Google Analytics 和 Google+ Badge 都使用了這種非同步載入代碼
(function(){;
var ga = document.createElement('script');
ga.type = 'text/javascript';
ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ga, s);
})();

但是這種載入方式執行完之前會阻止onload事件的觸發,而現在很多頁面的代碼都在onload時還執行額外的渲染工作,所以還是會阻塞部分頁面的初始化處理。
方法二:onload時的非同步載入
(function(){
if(window.attachEvent){
window.attachEvent("load", asyncLoad);
}else{
window.addEventListener("load", asyncLoad);
}
var asyncLoad = function(){
var ga = document.createElement('script');
ga.type = 'text/javascript';
ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ga, s);
}
)();

這種方法只是把插入script的方法放在一個函數裡面,然後放在window的onload方法裡面執行,這樣就解決了阻塞onload事件觸發的問題。
注:DOMContentLoaded與load的區別。前者是在document已經解析完成,頁面中的dom元素可用,但是頁面中的圖片,視頻,音頻等資源未載入完,作用同jQuery中的ready事件;後者的區別在於頁面所有資源全部載入完畢。
方法三:其他方法
由於JavaScript的動態性,還有很多非同步載入方法: XHR Injection、 XHR Eval、 Script In Iframe、 Script defer屬性、 document.write(script tag)。
XHR Injection(XHR 注入):通過XMLHttpRequest來獲取javascript,然後創建一個script元素插入到DOM結構中。ajax請求成功後設置script.text為請求成功後返回的responseText。
//獲取XMLHttpRequest對象,考慮兼容性。
var getXmlHttp = function(){
var obj;
if (window.XMLHttpRequest)
obj = new XMLHttpRequest();
else
obj = new ActiveXObject("Microsoft.XMLHTTP");
return obj;
};
//採用Http請求get方式;open()方法的第三個參數表示採用非同步(true)還是同步(false)處理
var xmlHttp = getXmlHttp();
xmlHttp.open("GET", "http://cdn.bootcss.com/jquery/3.0.0-beta1/jquery.min.js", true);
xmlHttp.send();
xmlHttp.onreadystatechange = function(){
if (xmlHttp.readyState == 4 && xmlHttp.status == 200){
var script = document.createElement("script");
script.text = xmlHttp.responseText;
document.getElementsByTagName("head")[0].appendChild(script);
}
}

XHR Eval:與XHR Injection對responseText的執行方式不同,直接把responseText放在eval()函數裡面執行。
//獲取XMLHttpRequest對象,考慮兼容性。
var getXmlHttp = function(){
var obj;
if (window.XMLHttpRequest)
obj = new XMLHttpRequest();
else
obj = new ActiveXObject("Microsoft.XMLHTTP");
return obj;
};
//採用Http請求get方式;open()方法的第三個參數表示採用非同步(true)還是同步(false)處理
var xmlHttp = getXmlHttp();
xmlHttp.open("GET", "http://cdn.bootcss.com/jquery/3.0.0-beta1/jquery.min.js", true);
xmlHttp.send();
xmlHttp.onreadystatechange = function(){
if (xmlHttp.readyState == 4 && xmlHttp.status == 200){
eval(xmlHttp.responseText);
//alert($);//可以彈出$,表明JS已經載入進來。click事件放在其它出會出問題,應該是還沒載入進來
$("#btn1").click(function(){
alert($(this).text());
});
}
}

Script In Irame:在父窗口插入一個iframe元素,然後再iframe中執行載入JS的操作。
var insertJS = function(){alert(2)};
var iframe = document.createElement("iframe");
document.body.appendChild(iframe);
var doc = iframe.contentWindow.document;//獲取iframe中的window要用contentWindow屬性。
doc.open();
doc.write("<script>var insertJS = function(){};<\/script><body onload='insertJS()'></body>");
doc.close();

GMail Mobile:業內JS內容被注釋,所以不會執行,在需要的時候,獲取script中的text內容去掉注釋,調用eval()執行。
<script type="text/javascript">
/*
var ...
*/
</script>

HTML5新屬性:async和defer屬性
defer屬性:IE4.0就出現。defer屬聲明腳本中將不會有document.write和dom修改。瀏覽器會並行下載其他有defer屬性的script。而不會阻塞頁面後續處理。註:所有的defer腳本必須保證按順序執行的。
<script type="text/javascript" defer></script>

async屬性:HTML5新屬性。腳本將在下載後盡快執行,作用同defer,但是不能保證腳本按順序執行。他們將在onload事件之前完成。
<script type="text/javascript" defer></script>

Firefox 3.6、Opera 10.5、IE 9和最新的Chrome和Safari都支持async屬性。可以同時使用async和defer,這樣IE 4之後的所有IE都支持非同步載入。
沒有async屬性,script將立即獲取(下載)並執行,期間阻塞了瀏覽器的後續處理。如果有async屬性,那麼script將被非同步下載並執行,同時瀏覽器繼續後續的處理。
總結: 對於支持HTML5的瀏覽器,實現JS的非同步載入只需要在script元素中加上async屬性,為了兼容老版本的IE還需加上defer屬性;對於不支持HTML5的瀏覽器(IE可以用defer實現),可以採用以上幾種方法實現。原理基本上都是向DOM中寫入script或者通過eval函數執行JS代碼,你可以把它放在匿名函數中執行,也可以在onload中執行,也可以通過XHR注入實現,也可以創建一個iframe元素,然後在iframe中執行插入JS代碼。

⑵ js單線程和js非同步操作的幾種方法

為了解決這個問題,Javascript語言將任務的執行模式分成兩種:同步(Synchronous)和非同步(Asynchronous)。
"同步模式"就是上一段的模式,後一個任務等待前一個任務結束,然後再執行,程序的執行順序與任務的排列順序是一致的、同步的;"非同步模式"則完全不同,每一個任務有一個或多個回調函數(callback),前一個任務結束後,不是執行後一個任務,而是執行回調函數,後一個任務則是不等前一個任務結束就執行,所以程序的執行順序與任務的排列順序是不一致的、非同步的。
"非同步模式"非常重要。在瀏覽器端,耗時很長的操作都應該非同步執行,避免瀏覽器失去響應,最好的例子就是Ajax操作。在伺服器端,"非同步模式"甚至是唯一的模式,因為執行環境是單線程的,如果允許同步執行所有http請求,伺服器性能會急劇下降,很快就會失去響應。

⑶ 如何進行nodejs非同步編程

更新下,我之所以讓您玩一下AJAX,是希望您體驗一下非同步,並不是希望您了解AJAX這機制的實現方法,因為AJAX是一個特別典型且簡單的非同步場景,比如:

行某個函數 -> 執行語句A,B,C,D -> 在D語句發起非同步請求,同時向引擎注冊一個回調事件 -> 執行E,F,G
->退出函數塊 ,引擎Loop...Loop...Loop,此時非同步的請求得到了Response,之前注冊的回調被執行。

@VILIC VANE
也提到了,實際上Node.js主要是為了應對主流web
app存在大量I/O等待而CPU閑置的場景所衍生的解決方案,而在架構上,它的後端有一個底層的worker封裝,每當你有一個諸如addUser這樣
的I/O操作時,它們都會被交由worker去執行從而達到讓出盡快讓出當前函數的執行權的目的,在向引擎注冊完回調後,內部會通過事件輪詢去檢查該I
/O事件的句柄,當句柄顯示該事件操作完成後,則注冊的回調則被執行。

所以,假設有人(按題設,簡化一下場景,有且只有2個人)同時請求
addUser(A)和userList(B),B的請求會在執行完A的請求內部所有同步代碼後被執行,而哪怕worker此時仍然在進行addUser
這一 I/O操作,用戶B也並不會被引擎掛起或者等待。這就是為什麼Node.js單節點卻一樣可以擁有高負載能力的原因。

至於什麼樣的代碼是非同步的,你看看node文檔里fs模塊的使用方法就知道了,大概的形式就是如下這種。
mole.method( args [,callback] )

當然還有一種比較極端的情況,假設您使用的資料庫是山寨的,驅動是基於同步實現的,那麼B就該等多久等多久把,樹蔭底下喝杯茶,下個棋,和後面的C,D,E,F,G打個招呼唄~
我推薦您先去玩一下前端的AJAX了解一下 非同步編程方式,體驗一下非同步的「感覺」,然後看一本叫《JavaScript非同步編程》的書。

Node.js

是一款基於Event-driven的模型構建的Framework,它典型的特徵就是通過內置的事件輪詢來調度事件,通常來說node.js的資料庫驅
動都是基於非同步實現的,所以在實際情況中,A提交博客和B注冊用戶這兩個請求是可以同時由Node.js
來handle,並按照實際操作的處理事件分別調度給予瀏覽器響應。

當然,假設您在業務代碼里寫了一個耗時很久的同步代碼(比如直接寫一
個while(true)的loop,Node就死了),由於JavaScript本身單線程的限制,所以整個App就會被block住,後續的事件/程
序只有等到該段代碼執行完成之後才會被處理,這也是為什麼我們通常不建議在Node.js層做大規模計算(JS本身的計算效率太低,會導致Node吞吐量
會大大降低),而傾向由C++的拓展去實現。

⑷ > 如何將JS代碼更換成非同步統計代碼

網站統計非同步代碼以非同步載入形式載入網站分析代碼,使用該代碼可以大幅提升網站的響應速度。
注意:使用非同步代碼不提供顯示統計圖標。

如何更新部署非同步統計代碼?
第一步:找到原js代碼,比如如下:
<scriptsrc='http://w.cnzz.com/c.php?id=XXXXXXXX&l=2'language='JavaScript'charset='gb2312'></script>

第二步:把原代碼替換成如下片段,然後上傳伺服器:
<script>
varcnzz_s_tag=document.createElement('script');
cnzz_s_tag.type='text/javascript';
cnzz_s_tag.async=true;
cnzz_s_tag.charset=「utf-8」;
cnzz_s_tag.src=「http://w.cnzz.com/c.php?id=XXXXXXXX&async=1」;
varroot_s=document.getElementsByTagName('script')[0];
root_s.parentNode.insertBefore(cnzz_s_tag,root_s);
</script>

添加好非同步統計代碼之後,一定要刪除原來默認統計代碼,否則統計數據會重復計算。
註:若是https的網站,把上面代碼里的http改成https即可

⑸ javascript同步和非同步的區別與實現方式

舉個生活中的示例就會很明白:

如:

早上起床,先刷牙,再燒水,等水燒開了洗臉,再整理發型.是同步

先刷牙,再燒水,再整理發型,等水壺滴的一聲通知我水燒開了,我再取剛燒開的水洗臉,是非同步.

<script>
varflag=false;
functionfuncTest(t,func){
setTimeout(function(){
(function(param){
console.log(param);
func();
}(t));
},t*1000);
}
varfuncList=[];
funcList.push(function(){funcTest(4,function(){
flag=true;//同步標記量
})});//不同的非同步函數添加進隊列
funcList.push(function(){funcTest(3,function(){
flag=true;
})});//不同的非同步函數添加進隊列
funcList.push(function(){funcTest(2,function(){
flag=true;
})});//不同的非同步函數添加進隊列
dealFuncSync(funcList);
functiondealFuncSync(funcList){
functioncallBackSync(){
if(!funcList||funcList.length==0){
console.log('end');
return;
}
flag=false;
funcList.shift()();
setTimeout(function(){
if(flag){//控制隊列函數同步
callBackSync();
}else{
setTimeout(arguments.callee,100);
}
},100);
}
callBackSync();
}
</script>

⑹ 如何優雅地寫 JS 非同步循環

用yield

示例如下:

//非同步函數
function*a(param){
console.log(param)
}
//循環
vartask=[]
for(vari=0;i<10;i++){
task.push(a(i))
}
//執行
varhandles=yieldtask

console.log(handles)

⑺ nodejs 非同步應該如何處理

結果當然是空數組因為非同步,會先執行console.log(),要想得到只能把console.log()寫在內回調函數容里。回調函數是當函數執行結束後才會調用的。
var fileArr = [];
//讀取文件目錄
fs.readdir(lastest_pages_path,function(err,files){
if(err){
console.log(err);
return;
}
fileArr.push(files);
console.log(fileArr);
}

⑻ js如何非同步執行方法

functionmyThread(callback){

returnsetTimeout(1000*10,function(){

$("#div").append("<p>hello</p>");//10秒後在div中加一個行,然後在執行callback函數

callback();

});

}

用回調內函容數

functionA(fun){

vartemp=100;

temp=temp*temp;

window.setTimeout(function(){

fun(temp);

},0);

alert("a函數:"+temp);

}

functionB(r){

alert("b函數"+r);

}

A(B);//調用
閱讀全文

與js寫成非同步處理相關的資料

熱點內容
word使用教程下載 瀏覽:295
電腦文件平鋪圖片默認大小 瀏覽:115
文件查看設置信息失敗 瀏覽:668
編程如何編出烏鴉喝水的課文 瀏覽:20
國家反詐app報案助手怎麼使用 瀏覽:439
秘密文件丟失多少天 瀏覽:237
js中csstext 瀏覽:382
目標文件名過長復制 瀏覽:892
樂動力計步器老版本 瀏覽:933
壓縮文件鏈接怎麼編輯 瀏覽:808
如何鎖定PDF文件里的圖章 瀏覽:89
資料庫超時是什麼 瀏覽:649
文件怎麼改整列內容 瀏覽:764
360壓縮文件發郵件空白 瀏覽:813
上哪裡查自己大數據 瀏覽:907
編程語言怎麼學車 瀏覽:189
編程該怎麼學才能先找工作 瀏覽:524
文件刻制光碟多少錢 瀏覽:861
校園網的網路組成結構 瀏覽:862
u盤系統復制文件過大 瀏覽:843

友情鏈接