導航:首頁 > 編程語言 > js如何實現非同步載入

js如何實現非同步載入

發布時間:2021-03-24 03:52:07

javaScript的非同步實現機制,是怎麼實現的

js能非同步是因為它用能調用的模塊是非同步的。
js都是單線程的。而且只版有一個事件隊列(也可權以理解成任務隊列)
他之所以非同步是是因為某些的模塊是非同步的。
當發送一個非同步網路請求後,js的主線程不會一直等待這個請求返回,而是執行事件隊列里下一個事件。
請注意,js並沒有實現如何發送網路請求,js只是調用了某個能發送網路請求的模塊,而這個模塊是通過c++或其他語言實現。然後這個模塊在等待請求的結果,當得到響應後,便把響應成功這個事件添加到js的事件隊列的隊尾。
網路請求發送的同時,js依然在執行,這顯然是非同步的。

⑵ javascript腳本如何非同步載入,有什麼作用

使用ajax就可以使用非同步載入。推薦使用jquery實現非同步載入。使用原生js開發速度會下降很多。
這邊有一篇使用jq實現非同步載入後台數據。
http://www.daimatree.com/tag_jq/tag_jq_ajax.php

⑶ 在js中如何對通過ajax方式非同步載入的一段js進行調試

嗯,如果你可以修改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);
})();
方法二: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);
}
})();

方法三:$(document).ready()

⑸ 怎樣實現javascript代碼的非同步載入

實現javascript代碼的非同步載入方式:

1、常見非同步載入(Script DOM Element)

(function(){
vars=document.createElement('script');
s.type='text/javascript';
s.async=true;
s.src='http://yourdomain.com/script.js';
varx=document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s,x);
})();

非同步載入又叫非阻塞,瀏覽器在下載執行 js 同時,還會繼續進行後續頁面的處理。

這種方法是在頁面中<script>標簽內,用 js 創建一個 script 元素並插入到 document 中。這樣就做到了非阻塞的下載 js 代碼。

async屬性是HTML5中新增的非同步支持,見後文解釋,加上好(不加也不影響)。

此方法被稱為Script DOM Element 法,不要求 js 同源。

將js代碼包裹在匿名函數中並立即執行的方式是為了保護變數名泄露到外部可見,這是很常見的方式,尤其是在 js 庫中被普遍使用。

例如 Google Analytics 和Google+Badge 都使用了這種非同步載入代碼:

(function(){
varga=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';
vars=document.getElementsByTagName('script')[0];s.parentNode.insertBefore(ga,s);
})();
(function()
{varpo=document.createElement("script");
po.type="text/javascript";po.async=true;po.src="https://apis.google.com/js/plusone.js";
vars=document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(po,s);
})();

但是,這種載入方式在載入執行完之前會阻止 onload 事件的觸發,而現在很多頁面的代碼都在 onload 時還要執行額外的渲染工作等,所以還是會阻塞部分頁面的初始化處理。

2、onload 時的非同步載入

(function(){
functionasync_load(){
vars=document.createElement('script');
s.type='text/javascript';
s.async=true;
s.src='http://yourdomain.com/script.js';
varx=document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s,x);
}
if(window.attachEvent)
window.attachEvent('onload',async_load);
else
window.addEventListener('load',async_load,false);
})();

這和前面的方式差不多,但關鍵是它不是立即開始非同步載入 js ,而是在 onload 時才開始非同步載入。這樣就解決了阻塞 onload 事件觸發的問題。

補充:DOMContentLoaded 與OnLoad 事件

DOMContentLoaded : 頁面(document)已經解析完成,頁面中的dom元素已經可用。但是頁面中引用的圖片、subframe可能還沒有載入完。

OnLoad:頁面的所有資源都載入完畢(包括圖片)。瀏覽器的載入進度在這時才停止。

這兩個時間點將頁面載入的timeline分成了三個階段。

3、非同步載入的其它方法

由於Javascript的動態特性,還有很多非同步載入方法:

XHREval
XHRInjection
ScriptinIframe
ScriptDefer
document.writeScriptTag

還有一種方法是用 setTimeout 延遲0秒 與 其它方法組合。

XHR Eval:通過 ajax 獲取js的內容,然後 eval 執行。

varxhrObj=getXHRObject();
xhrObj.onreadystatechange=
function(){
if(xhrObj.readyState!=4)return;
eval(xhrObj.responseText);
};
xhrObj.open('GET','A.js',true);
xhrObj.send('');

Script in Iframe:創建並插入一個iframe元素,讓其非同步執行 js 。

variframe=document.createElement('iframe');
document.body.appendChild(iframe);
vardoc=iframe.contentWindow.document;
doc.open().write('<bodyonload="insertJS()">');
doc.close();

GMail Mobile:頁內 js 的內容被注釋,所以不會執行,然後在需要的時候,獲取script元素中 text 內容,去掉注釋後 eval 執行。

<scripttype="text/javascript">
/*
var...
*/
</script>

詳見參考資料中2010年的Velocity 大會 Steve Souders 和淘寶的那兩個講義。

⑹ 如何實現JS非同步載入

用jq的話抄
$.ajax({
url:'www..com',
type:'get',
async:true, //默認襲是ture 就是非同步。。想要同步就是 false
success:function(res){
//code

}
})

⑺ 怎樣用JS實現非同步轉同步

源起

小飛是一名剛入行前端不久的新人,因為進到了某個大公司,儼然成為了學弟學妹眼中'大神',大家遇到js問題都喜歡問他,這不,此時他的qq彈出了這樣一條消息

"hi,大神在嗎?我有個問題想問,現在我們的代碼裡面有這樣的東西,可是得不到正確的返回結果

1234567functiongetDataByAjax () {return$.ajax(...postParam)}vardata = getDataByAjax()if(data) {console.log(data.info)}

"哦,你這里是非同步調用,不能直接獲得返回值,你要把if語句寫到回調函數中",小飛不假思索的說到,對於一個『專業』的fe來說,這根本不是一個問題。
「可是我希望只是改造getDataByAjax這個方法,讓後面的代碼成立。」
「研究這個沒有意義,非同步是js的精髓,同步的話會阻塞js調用,超級慢的,但是你要一再堅持的話,用async:true就好了」
「不愧是大神,我回去立刻試一試,么么噠」

兩天後,她哭喪著臉登上了qq
「試了一下你的方法,但是根本行不通,哭~~」
「別急,我看看你這個postParam的參數行嗎」

123456{...dataType:'jsonp',async:true...}

"這是一個jsonp請求啊,老掉牙的東西了,,jsonp請求是沒有辦法同步的"
「我知道jsonp請求的原理是通過script標簽實現的,但是,你看,script也是支持同步的呀,你看tags/attscriptasync.asp」
「額,那可能是jquery沒有實現吧,哈哈」
「大神,你能幫我實現一個jsonp的同步調用方式嘛,拜託了(星星眼)」
雖然他有點奇怪jquery為什麼沒有實現,但是既然w3school的標准擺在那裡,碼兩行代碼又沒什麼,

loadJsonpSync = (url) => {varresult;window.callback1 = (data) => (result = data)lethead = window.document.getElementsByTagName('head')[0]letjs = window.document.createElement('script')js.setAttribute('type','text/javascript')js.setAttribute('async','sync')// 這句顯式聲明強調src不是按照非同步方式調用的js.setAttribute('src', url)head.appendChild(js)returnresult}

額,運行起來結果竟然是undefined!w3cshool的文檔竟然也不準,還權威呢,我看也不怎麼著,小飛暗自想到。

「剛才試了一下,w3school文檔上寫的有問題,這個非同步屬性根本就是錯的」
「可是我剛還試過一次這個,我確認是好的呀」

12<script src="loop50000 && put('frist').js"></script><script src="put('second').js"></script>

(有興趣的同學可以實現以下兩個js,並且加上async的標簽進行嘗試。)
「這個,我就搞不清楚了」,小飛訕訕的說到
對方已離線

抽象

關於這個問題,相信不只是小飛,很多人都難以解答。為什麼ajax可以做到同步,但jsonp不行,推廣到nodejs上,為什麼readFile也可以做到同步(readFileSync),但有的庫卻不行。
(至於script的async選項我們暫時避而不談,是因為現在的知識維度暫時還不夠,但是不要著急,下文中會給出明確的解釋)
現在,讓我們以計算機科學的角度抽象這個問題:

我們是否可以將非同步代碼轉化為同步代碼呢?(ASYNCCALL => SYNCCALL)

既然是抽象問題,那麼我們就可以不從工程角度/性能角度/實現語言等等等方面來看(同步比非同步效率低下),每增加一個維度,復雜程度將以幾何爆炸般增長下去。

首先,我們來明確一點,==在計算機科學領域==同步和非同步的定義

同步(英語:Synchronization),指對在一個系統中所發生的事件(event)之間進行協調,在時間上出現一致性與統一化的現象。在系統中進行同步,也被稱為及時(in time)、同步化的(synchronous、in sync)。--摘自網路
非同步的概念和同步相對。即時間不一致,不統一

明確了這一點,我們可以藉助甘特圖來表示同步和非同步

注意看我們標紅的地方,如果你完成了小測驗1,就會得到和這張圖一致的順序

==同步執行的代碼片段必然在非同步之前。==

所以,無論從理論還是實際出發,我們都不得不承認,在js中,把非同步方法改成同步方法這個命題是水月鏡花

哦對了,最後還需要解釋一下最開始我們埋下的坑, 為什麼jsonp中的async沒有生效,現在解釋起來真的是相當輕松,即document.appendChild的動作是交由dom渲染線程完成的,所謂的async阻塞的是dom的解析,而非js引擎的阻塞。實際上,在async獲取資源後,與js引擎的交互依舊是push taskQueue的動作,也就是我們所說的async call

推薦閱讀: 關於dom解析請大家參考webkit技術內幕第九章資源載入部分

峰迴路轉

相信很多新潮的同學已經開始運用切了async/await語法,在下面的語法中,getAjax1和console之間的具有同步的特性

1234asyncfunction() {vardata = await getAjax1()console.log(data)}

講完了event loop和非同步的本質,我們來重新審視一下async/await。
老天,這段代碼親手推翻了==同步執行的代碼片段必然在非同步之前。== 的黃金定律!
驚不驚喜,意不意外,這在我們的模型里如同三體里的質子一樣的存在。我們重新審視了一遍上面的模型,實在找不到漏洞,找不到任何可以推翻的點,所以真的必須承認,async/await絕對是一個超級神奇的魔法。
到這里來看我們不得不暫時放棄前面的推論,從async/await本身來看這個問題
相信很多人都會說,async/await是CO的語法糖,CO又是generator/promise的語法糖,好的,那我們不妨去掉這層語法糖,來看看這種代碼的本質, 關於CO,讀的人太多了,我實在不好老生常談,可以看看這篇文章,咱們就直接繞過去了,這里給出一個簡易的實現
/5800210.html

functionwrap(wait) {variteriter = wait()const f = () => {const { value } = iter.next()value && value.then(f)}f()}function*wait() {varp = () =>newPromise(resolve => {setTimeout(() => resolve(), 3000)})yieldp()console.log('unlock1')yieldp()console.log('unlock2')console.log('it's sync!!')}

終於,我們發現了問題的關鍵,如果單純的看wait生成器(注意,不是普通的函數),是不是覺得非常眼熟。這就是我們最開始提出的spinlock偽代碼!!!
這個已經被我們完完全全的否定過了,js不可能存在自旋鎖,事出反常必有妖,是的,yield和*就是表演async/await魔法的妖精。
generator和yield字面上含義。Gennerator叫做生成器,yield這塊ruby,python,js等各種語言界爭議很大,但是大多數人對於『讓權』這個概念是認同的(以前看到過maillist上面的爭論,但是具體的內容已經找不到了)

擴展閱讀---ruby元編程 閉包章節yield(ruby語義下的yield)

所謂讓權,是指cpu在執行時讓出使用權利,操作系統的角度來看就是『掛起』原語,在eventloop的語義下,似乎是暫存起當時正在執行的代碼塊(在我們的eventloop裡面對應runPart),然後順序的執行下一個程序塊。
我們可以修改eventloop來實現讓權機制

小測驗2 修改eventloop使之支持yield原語

至此,通過修改eventloop模型固然可以解決問題,但是,這並不能被稱之為魔法。

和諧共存的世界

實際上通過babel,我們可以輕松的降級使用yield,(在es5的世界使用讓權的概念!!)
看似不可能的事情,現在,讓我們撿起曾經論證過的
==同步執行的代碼片段必然在非同步之前。== 這個定理,在此基礎上進行進行逆否轉化

==在非同步代碼執行之後的代碼必然不是同步執行的(非同步的)。==

這是一個圈子裡人盡皆知的話,但直到現在他才變得有說服力(我們繞了一個好長的圈子)
現在,讓我們允許使用callback,不使用generator/yield的情況下完成一個wait generator相同的功能!!!

functionwait() {const p = () => ({value:newPromise(resolve => setTimeout(() => resolve(), 3000))})letstate = {next: () => {state.next = programPartreturnp()}}functionprogramPart() {console.log('unlocked1')state.next = programPart2returnp()}functionprogramPart2() {console.log('unlocked2')console.log('it's sync!!')return{value: void 0}}returnstate}

太棒了,我們成功的完成了generator到function的轉化(雖然成本高昂),同時,這段代碼本身也解釋清楚了generator的本質,高階函數,片段生成器,或者直接叫做函數生成器!這和scip上的翻譯完全一致,同時擁有自己的狀態(有限狀態機)

推薦閱讀 計算機程序的構造和解釋 第一章generator部分
小測驗3 實際上我們提供的解決方式存在缺陷,請從作用域角度談談

其實,在不知不覺中,我們已經重新發明了計算機科學中大名鼎鼎的CPS變換
Continuation-passing_style

最後的最後,容我向大家介紹一下facebook的CPS自動變換工具--regenerator。他在我們的基礎上修正了作用域的缺陷,讓generator在es5的世界裡自然優雅。我們向facebook脫帽致敬!!egenerator

後記

同步非同步 可以說是整個圈子裡面最喜歡談論的問題,但是,談來談去,似乎絕大多數變成了所謂的『約定俗稱』,大家意味追求新技術的同時,卻並不關心新技術是如何在老技術上傳承發展的,知其然而不知其所以然,人雲亦雲的寫著似是而非的js。

==技術,不應該浮躁==

PS: 最大的功勞不是CO,也不是babel。regenerator的出現比babel早幾個月,而且最初的實現是基於esprima/recast的,關於resprima/recast,國內似乎了解的並不多,其實在babel剛剛誕生之際, esprima/esprima-fb/acron 以及recast/jstransfrom/babel-generator幾大族系圍繞著react產生過一場激烈的斗爭,或許將來的某一天,我會再從實現細節上談一談為什麼babel笑到了最後~~~~

⑻ js怎麼非同步載入loading

js非同步載入loading的方法復如下制:
1、獲取載入的圖片
var image = document.images[0];
2、手動創建一個image對象
var downloadingImage = new Image();
3、調用onload事件載入src真正的鏈接地址
downloadingImage.onload = function(){
image.src = this.src; //src後置指定
};
downloadingImage.src = "目標圖片地址";

⑼ require.js怎樣非同步載入模塊

最早的時候,所來有Javascript代碼源都寫在一個文件裡面,只要載入這一個文件就夠了。後來,代碼越來越多,一個文件不夠了,必須分成多個文件,依次載入。下面的網頁代碼,相信很多人都見過。 <script src="1.js"></script> <script src="2.js"></script> <script src="3.js"></script> <script src="4.js"></script> <script src="5.js"></script> <script src="6.js"></script> 這段代碼依次載入多個js文件。 這樣的寫法有很大的缺點。首先,載入的時候,瀏覽器會停止網頁渲染,載入文件越多,網頁失去響應的時間就會越長;其次,由於js文件之間存在依賴關系,因此必須嚴格保證載入順序(比如上例的1.js要在2.js的前面),依賴性最大的模塊一定要放到最後載入,當依賴關系很復雜的時候,代碼的編寫和維護都會變得困難。 require.js的誕生

⑽ 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如何實現非同步載入相關的資料

熱點內容
怎麼用公式比對兩列數據 瀏覽:283
交保險的app有哪些 瀏覽:559
2017年蘋果5s可以買嘛 瀏覽:153
加密文件在什麼地方找不到了 瀏覽:676
網卡驅動文件夾 瀏覽:444
iphone6qq關聯賬號顯示台機 瀏覽:709
java文件名亂碼 瀏覽:553
什麼是網橋編程固件 瀏覽:732
jquery實現網站向導提示操作插件 瀏覽:257
java小游戲實例 瀏覽:775
電腦系統能升級64 瀏覽:591
數據如何導入進sql 瀏覽:324
iosqq怎麼發文件夾 瀏覽:285
編程出社會後能做什麼工作 瀏覽:73
為什麼說數據層是里子呢 瀏覽:171
eset官方卸載工具 瀏覽:803
手機百度我在哪個文件夾 瀏覽:646
lumia925拍照對蘋果6 瀏覽:599
oraclelinux711gr2 瀏覽:516
公文格式圖片紅頭文件 瀏覽:430

友情鏈接