欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

小試JavaScript多線程第2/2頁(yè)

 更新時(shí)間:2025年03月02日 21:42:09   投稿:mdxy-dxy  
這兩天一直在弄ajax,用多了才發(fā)現(xiàn)了ajax?的cache問(wèn)題,請(qǐng)求了好多次,得到了確是相同的結(jié)果,經(jīng)常我想在請(qǐng)求的同時(shí)去做一些其它的事情,我在想javascript里有沒(méi)有辦法用多線程,經(jīng)過(guò)在網(wǎng)上查找找到了結(jié)果。

這個(gè)程序也在內(nèi)部調(diào)用了getArticle()函數(shù)。然而需要注意的是,為異步通信設(shè)計(jì)的這版getArticle()函數(shù)要接收一個(gè)函數(shù)作為第二個(gè)參數(shù)。當(dāng)調(diào)用這個(gè)getArticle()函數(shù)時(shí),與從前一樣要給服務(wù)器發(fā)送一個(gè)請(qǐng)求,不同的是,現(xiàn)在函數(shù)會(huì)迅速返回而非等待服務(wù)器的響應(yīng)。這意味著,當(dāng)執(zhí)行權(quán)交回給調(diào)用程序時(shí),還沒(méi)有得到服務(wù)器的響應(yīng)。如此一來(lái),線程就可以去執(zhí)行其它任務(wù)直至獲得服務(wù)器響應(yīng),并在此時(shí)調(diào)用回調(diào)函數(shù)。一旦得到服務(wù)器響應(yīng), getArticle()的第二個(gè)參數(shù)作為預(yù)先定義的回調(diào)函數(shù)就要被調(diào)用,服務(wù)器的返回值即為其參數(shù)。同樣的,getArticleWithCache ()也要做些改變,定義一個(gè)回調(diào)參數(shù)作為其第二個(gè)參數(shù)。這個(gè)回調(diào)函數(shù)將在被傳給getArticle()的回調(diào)函數(shù)中調(diào)用,因而它可以在服務(wù)器通信結(jié)束后被執(zhí)行。
單是上面這些改動(dòng)你可能已經(jīng)認(rèn)為相當(dāng)復(fù)雜了,但是對(duì)backgroundLoad()函數(shù)做得改動(dòng)將會(huì)更復(fù)雜,它也要被改寫(xiě)成可以處理回調(diào)函數(shù)的形式:
function backgroundLoad ( ids, callback ) {
var i = 0;
function l ( ) {
if ( i < ids.length ) {
getArticleWithCache(ids[i++], function( a ){
backgroundLoad(a.children, l);
});
} else {
callback();
}
}
l();
}
改動(dòng)后的backgroundLoad()函數(shù)看上去和我們以前的那個(gè)函數(shù)已經(jīng)相去甚遠(yuǎn),不過(guò)他們所實(shí)現(xiàn)的功能并無(wú)二致。這意味著這兩個(gè)函數(shù)都接受 ID數(shù)組作為參數(shù),對(duì)于數(shù)組里的每個(gè)元素都要調(diào)用getArticleWithCache(),再應(yīng)用已經(jīng)獲得子文章ID遞歸調(diào)用 backgroundLoad ()。不過(guò)同樣是對(duì)數(shù)組的循環(huán)訪問(wèn),新函數(shù)中的就不太好辨認(rèn)了,以前的程序中是用一個(gè)for循環(huán)語(yǔ)句完成的。為什么實(shí)現(xiàn)同樣功能的兩套函數(shù)是如此的大相徑庭呢?
這個(gè)差異源于一個(gè)事實(shí):任何函數(shù)在遇到有需要同服務(wù)器進(jìn)行通信情況后,都必須立刻返回,例如getArticleWithCache()。除非原來(lái)的函數(shù)不在執(zhí)行當(dāng)中,否則應(yīng)當(dāng)接受服務(wù)器響應(yīng)的回調(diào)函數(shù)都不能被調(diào)用。對(duì)于JavaScript,在循環(huán)過(guò)程中中斷程序并在稍后從這個(gè)斷點(diǎn)繼續(xù)開(kāi)始執(zhí)行程序是不可能的,例如一個(gè)for語(yǔ)句。因此,本例利用遞歸傳遞回調(diào)函數(shù)實(shí)現(xiàn)循環(huán)結(jié)構(gòu)而非一個(gè)傳統(tǒng)循環(huán)語(yǔ)句。對(duì)那些熟悉連續(xù)傳送風(fēng)格(CPS)的人來(lái)說(shuō),這就是一個(gè) CPS的手動(dòng)實(shí)現(xiàn),因?yàn)椴荒苁褂醚h(huán)語(yǔ)法,所以即便如前面提到的遍歷樹(shù)那么簡(jiǎn)單的程序也得寫(xiě)得很復(fù)雜。與事件驅(qū)動(dòng)程序設(shè)計(jì)相關(guān)的問(wèn)題是控制流問(wèn)題:循環(huán)和其它控制流表達(dá)式可能比較難理解。
這里還有另外一個(gè)問(wèn)題:如果你把一個(gè)沒(méi)有應(yīng)用異步通信的函數(shù)轉(zhuǎn)換為一個(gè)使用異步通信的函數(shù),那么重寫(xiě)的函數(shù)將需要一個(gè)回調(diào)函數(shù)作為新增參數(shù),這為已經(jīng)存在的APIs造成了很大問(wèn)題,因?yàn)閮?nèi)在的改變沒(méi)有把影響限于內(nèi)部,而是導(dǎo)致整體混亂的APIs以及API的其它使用者的改變。
造成這些問(wèn)題目的根本原因是什么呢?沒(méi)錯(cuò),正是JavaScript單線程機(jī)制導(dǎo)致了這些問(wèn)題。在單線程里執(zhí)行異步通信需要事件驅(qū)動(dòng)程序設(shè)計(jì)和復(fù)雜的語(yǔ)句。如果當(dāng)程序在等待服務(wù)器的響應(yīng)時(shí),有另外一個(gè)線程可以來(lái)處理用戶請(qǐng)求,那么上述復(fù)雜技術(shù)就不需要了。
試試多線程編程
讓我來(lái)介紹一下Concurrent.Thread,它是一個(gè)允許JavaScript進(jìn)行多線程編程的庫(kù),應(yīng)用它可以大大緩解上文提及的在 AJAX開(kāi)發(fā)中與異步通信相關(guān)的困難。這是一個(gè)用JavaScript寫(xiě)成的免費(fèi)的軟件庫(kù),使用它的前提是遵守Mozilla Public License和GNU General Public License這兩個(gè)協(xié)議。你可以從他們的網(wǎng)站 下載源代碼。
馬上來(lái)下載和使用源碼吧!假定你已經(jīng)將下載的源碼保存到一個(gè)名為Concurrent.Thread.js的文件夾里,在進(jìn)行任何操作之前,先運(yùn)行如下程序,這是一個(gè)很簡(jiǎn)單的功能實(shí)現(xiàn):
<script type="text/javascript" src="Concurrent.Thread.js"> </script>
<script type="text/javascript">
Concurrent.Thread.create(function(){
var i = 0;
while ( 1 ) {
document.body.innerHTML += i++ + " <br>";
}
});
</script>
執(zhí)行這個(gè)程序?qū)?huì)順序顯示從0開(kāi)始的數(shù)字,它們一個(gè)接一個(gè)出現(xiàn),你可以滾屏來(lái)看它?,F(xiàn)在讓我們來(lái)仔細(xì)研究一下代碼,他應(yīng)用while(1)條件制造了一個(gè)不會(huì)中止的循環(huán),通常情況下,象這樣不斷使用一個(gè)并且是唯一一個(gè)線程的JavaScript程序會(huì)導(dǎo)致瀏覽器看起來(lái)象凍結(jié)了一樣,自然也就不會(huì)允許你滾屏。那么為什么上面的這段程序允許你這么做呢?關(guān)鍵之處在于while(1)上面的那條Concurrent.Thread.create()語(yǔ)句,這是這個(gè)庫(kù)提供的一個(gè)方法,它可以創(chuàng)建一個(gè)新線程。被當(dāng)做參數(shù)傳入的函數(shù)在這個(gè)新線程里執(zhí)行,讓我們對(duì)程序做如下微調(diào):
<script type="text/javascript" src="Concurrent.Thread.js"> </script>
<script type="text/javascript">
function f ( i ){
while ( 1 ) {
document.body.innerHTML += i++ + " <br>";
}
}
Concurrent.Thread.create(f, 0);
Concurrent.Thread.create(f, 100000);
</script>
在這個(gè)程序里有個(gè)新函數(shù)f()可以重復(fù)顯示數(shù)字,它是在程序段起始定義的,接著以f()為參數(shù)調(diào)用了兩次create()方法,傳給create()方法的第二個(gè)參數(shù)將會(huì)不加修改地傳給f()。執(zhí)行這個(gè)程序,先會(huì)看到一些從0開(kāi)始的小數(shù),接著是一些從100,000開(kāi)始的大數(shù),然后又是接著前面小數(shù)順序的數(shù)字。你可以觀察到程序在交替顯示小數(shù)和大數(shù),這說(shuō)明兩個(gè)線程在同時(shí)運(yùn)行。
讓我來(lái)展示Concurrent.Thread的另外一個(gè)用法。上面的例子調(diào)用create()方法來(lái)創(chuàng)建新線程。不調(diào)用庫(kù)里的任何APIs也有可能實(shí)現(xiàn)這個(gè)目的。例如,前面那個(gè)例子可以這樣寫(xiě):
<script type="text/javascript" src="Concurrent.Thread.js"> </script>
<script type="text/x-script.multithreaded-js">
var i = 1;
while ( 1 ) {
document.body.innerHTML += i++ + " <br>";
}
</script>
在script 標(biāo)簽內(nèi),很簡(jiǎn)單地用JavaScript寫(xiě)了一個(gè)無(wú)窮循環(huán)。你應(yīng)該注意到標(biāo)簽內(nèi)的type屬性,那里是一個(gè)很陌生的值(text/x- script.multithreaded-js),如果這個(gè)屬性被放在script標(biāo)簽內(nèi),那么Concurrent.Thread就會(huì)在一個(gè)新的線程內(nèi)執(zhí)行標(biāo)簽之間的程序。你應(yīng)當(dāng)記住一點(diǎn),在本例一樣,必須將Concurrent.Thread庫(kù)包含進(jìn)來(lái)。
有了Concurrent.Thread,就有可能自如的將執(zhí)行環(huán)境在線程之間進(jìn)行切換,即使你的程序很長(zhǎng)、連續(xù)性很強(qiáng)。我們可以簡(jiǎn)要地討論下如何執(zhí)行這種操作。簡(jiǎn)言之,需要進(jìn)行代碼轉(zhuǎn)換。粗略地講,首先要把傳遞給create()的函數(shù)轉(zhuǎn)換成一個(gè)字符串,接著改寫(xiě)直至它可以被分批分次執(zhí)行。然后這些程序可以依照調(diào)度程序逐步執(zhí)行。調(diào)度程序負(fù)責(zé)協(xié)調(diào)多線程,換句話說(shuō),它可以在適當(dāng)?shù)臅r(shí)候做出調(diào)整以便每一個(gè)修改后的函數(shù)都會(huì)得到同等機(jī)會(huì)運(yùn)行。 Concurrent.Thread實(shí)際上并沒(méi)有創(chuàng)建新的線程,僅僅是在原本單線程的基礎(chǔ)上模擬了一個(gè)多線程環(huán)境。
雖然轉(zhuǎn)換后的函數(shù)看起來(lái)是運(yùn)行在不同的線程內(nèi),但是實(shí)際上只有一個(gè)線程在做這所有的事情。在轉(zhuǎn)換后的函數(shù)內(nèi)執(zhí)行同步通信仍然會(huì)造成瀏覽器凍結(jié),你也許會(huì)認(rèn)為以前的那些問(wèn)題根本就沒(méi)有解決。不過(guò)你不必耽心,Concurrent.Thread提供了一個(gè)應(yīng)用JavaScript 的異步通信方式實(shí)現(xiàn)的定制通信庫(kù),它被設(shè)計(jì)成當(dāng)一個(gè)線程在等待服務(wù)器的響應(yīng)時(shí)允許其它線程運(yùn)行。這個(gè)通信庫(kù)存于 Concurrent.Thread.Http下。它的用法如下所示:
<script type="text/javascript" src="Concurrent.Thread.js"> </script>
<script type="text/x-script.multithreaded-js">
var req = Concurrent.Thread.Http.get(url, ["Accept", "*"]);
if (req.status == 200) {
alert(req.responseText);
} else {
alert(req.statusText);
}
</script>
get()方法,就像它的名字暗示的那樣,可以通過(guò)HTTP的GET方法獲得指定URL的內(nèi)容,它將目標(biāo)URL作為第一個(gè)參數(shù),將一個(gè)代表HTTP 請(qǐng)求頭的數(shù)組作為可選的第二個(gè)參數(shù)。get()方法與服務(wù)器交互,當(dāng)?shù)玫椒?wù)器的響應(yīng)后就返回一個(gè)XMLHttpRequest對(duì)象作為返回值。當(dāng) get()方法返回時(shí),已經(jīng)收到了服務(wù)器響應(yīng),所以就沒(méi)必要再用回調(diào)函數(shù)接收結(jié)果。自然,也不必再耽心當(dāng)程序等待服務(wù)器的響應(yīng)時(shí)瀏覽器凍結(jié)的情況了。另外,還有一個(gè) post()方法可以用來(lái)發(fā)送數(shù)據(jù)到服務(wù)器:
<script type="text/javascript" src="Concurrent.Thread.js"> </script>
<script type="text/x-script.multithreaded-js">
var req = Concurrent.Thread.Http.post(url, "key1=val1&key2=val2");
alert(req.statusText);
</script>
post()方法將目的URL作為第一個(gè)參數(shù),要發(fā)送的內(nèi)容作為第二個(gè)參數(shù)。像get()方法那樣,你也可以將請(qǐng)求頭作為可選的第三個(gè)參數(shù)。
如果你用這個(gè)通信庫(kù)實(shí)現(xiàn)了第一個(gè)例子當(dāng)中的getArticle()方法,那么你很快就能應(yīng)用文章開(kāi)頭示例的那種簡(jiǎn)單的方法寫(xiě)出 getArticleWithCache(),backgroundLoad ()以及其它調(diào)用了getArticle()方法的函數(shù)了。即使是那版backgroundLoad()正在讀文章數(shù)據(jù),照例還有另外一個(gè)線程可以對(duì)用戶請(qǐng)求做出響應(yīng),瀏覽器因此也不會(huì)凍結(jié)?,F(xiàn)在,你能理解在JavaScript中應(yīng)用多線程有多實(shí)用了?
想了解更多
我向你介紹了一個(gè)可以在JavaScript中應(yīng)用多線程的庫(kù):Concurrent.Thread。這篇文章的內(nèi)容只是很初級(jí)的東西,如果你想更深入的了解,我推薦您去看the tutorial。它提供有關(guān)Concurrent.Thread用法的更多內(nèi)容,并列出了可供高級(jí)用戶使用的文檔,是最適合起步的材料。訪問(wèn)他們的網(wǎng)站也不錯(cuò),那里提供更多信息。
有關(guān)作者
Daisuke Maki:從 International Christian大學(xué)文科學(xué)院自然科學(xué)分部畢業(yè)后(取得文學(xué)學(xué)士學(xué)位),又在Electro-Communications大學(xué)的研究生院信息專(zhuān)業(yè)攻讀碩士學(xué)位。擅長(zhǎng)Web開(kāi)發(fā)和應(yīng)用JavaScript的AJAX。他開(kāi)發(fā)了Concurrent.Thread。2006財(cái)政年度在日本信息技術(shù)促進(jìn)機(jī)構(gòu)(IPA)指導(dǎo)的項(xiàng)目Explatory Software Project中應(yīng)用了這個(gè)設(shè)計(jì)。
目前已經(jīng)擁有一個(gè)工學(xué)碩士學(xué)位的他正在Electro-Communications大學(xué)的研究生院注冊(cè)攻讀博士學(xué)位。
下載地址//www.dbjr.com.cn/jiaoben/8626.html

相關(guān)文章

  • Bootstrap3學(xué)習(xí)筆記(二)之排版

    Bootstrap3學(xué)習(xí)筆記(二)之排版

    這篇文章主要介紹了Bootstrap3學(xué)習(xí)筆記(二)之排版的相關(guān)資料,非常具有參考價(jià)值,特此分享腳本之家平臺(tái),供大家參考
    2016-05-05
  • JS判斷點(diǎn)是否在線段上的代碼

    JS判斷點(diǎn)是否在線段上的代碼

    這篇文章主要介紹了JS判斷點(diǎn)是否在線段上的相關(guān)資料,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-11-11
  • 分享一款超好用的JavaScript 打包壓縮工具

    分享一款超好用的JavaScript 打包壓縮工具

    這篇文章主要介紹了寫(xiě)一個(gè)飛快的 JavaScript 打包壓縮工具,非常好用,本文給大家分享實(shí)現(xiàn)思路,需要的朋友可以參考下
    2020-04-04
  • JS基于for語(yǔ)句編寫(xiě)的九九乘法表示例

    JS基于for語(yǔ)句編寫(xiě)的九九乘法表示例

    這篇文章主要介紹了JS基于for語(yǔ)句編寫(xiě)的九九乘法,涉及for語(yǔ)句循環(huán)輸出結(jié)合table表格布局實(shí)現(xiàn)九九乘法功能的相關(guān)操作技巧,需要的朋友可以參考下
    2018-01-01
  • 用 javascript 實(shí)現(xiàn)的點(diǎn)擊復(fù)制代碼

    用 javascript 實(shí)現(xiàn)的點(diǎn)擊復(fù)制代碼

    用 javascript 實(shí)現(xiàn)的點(diǎn)擊復(fù)制代碼,需要的朋友可以參考一下
    2007-03-03
  • 用js+xml自動(dòng)生成表格的東西

    用js+xml自動(dòng)生成表格的東西

    用js+xml自動(dòng)生成表格的東西...
    2006-12-12
  • 為什么說(shuō)JavaScript預(yù)解釋是一種毫無(wú)節(jié)操的機(jī)制詳析

    為什么說(shuō)JavaScript預(yù)解釋是一種毫無(wú)節(jié)操的機(jī)制詳析

    這篇文章主要給大家介紹了關(guān)于為什么說(shuō)JavaScript預(yù)解釋是一種毫無(wú)節(jié)操的機(jī)制的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧
    2018-11-11
  • uniapp導(dǎo)航欄組件使用步驟

    uniapp導(dǎo)航欄組件使用步驟

    在uni-app中,可以使用官方提供的uni-navigator組件來(lái)實(shí)現(xiàn)導(dǎo)航欄的功能,這篇文章主要介紹了uniapp導(dǎo)航欄組件如何使用,需要的朋友可以參考下
    2024-01-01
  • JavaScript數(shù)組操作函數(shù)匯總

    JavaScript數(shù)組操作函數(shù)匯總

    這篇文章主要針對(duì)JavaScript數(shù)組操作函數(shù)push,pop,join,shift,unshift,slice,splice,concat進(jìn)行總結(jié),感興趣的小伙伴們可以參考一下
    2016-08-08
  • echarts提示框tooltip被遮擋的解決辦法分享

    echarts提示框tooltip被遮擋的解決辦法分享

    這篇文章主要給大家介紹了關(guān)于echarts提示框tooltip被遮擋的解決辦法, 在制作圖表中,發(fā)現(xiàn)有時(shí)候tooltip會(huì)被線條遮擋或者被柱子折線遮擋,這種情況會(huì)偶爾出現(xiàn),需要的朋友可以參考下
    2023-08-08

最新評(píng)論