JavaScript マルチスレッドを試す ページ 1/2_JavaScript スキル

PHP中文网
リリース: 2016-05-16 18:58:27
オリジナル
895 人が閲覧しました

ここ 2 日間、ajax を使って作業していましたが、何度もリクエストを行った結果、ajax のキャッシュの問題が発生しました。リクエスト中に他のことをやりたくなることがよくあります。 JavaScript でマルチスレッドを使用する方法はないかと考え、オンラインで検索した結果を見つけました。

魔法の武器は Concurrent.Thread で、実際には Web サイトからソースコードをダウンロードできます。
それは非常に簡単です
Concurrent.Thread.create。 (f, a1, a2, ...) f は呼び出したい関数、a1、a2 は関数のパラメータです。これにより、複数のスレッドを同時に作成でき、それらが実行されます。このライブラリは、Concurrent.Thread.stop() などの他の言語のスレッド使用メソッドと同様に、同時に多くのメソッドを提供します。具体的に知りたい場合は、Web サイトにアクセスしてください。


<html> 
<body> 
<script type="text/javascript" src="Concurrent.Thread.Compiler.js"></script> 
<script type="text/javascript"> 
function hello ( ) { 
document.body.innerHTML += "H"; 
document.body.innerHTML += "e"; 
document.body.innerHTML += "l"; 
document.body.innerHTML += "l"; 
document.body.innerHTML += "o"; 
document.body.innerHTML += ","; 
document.body.innerHTML += " "; 
document.body.innerHTML += "w"; 
document.body.innerHTML += "o"; 
document.body.innerHTML += "r"; 
document.body.innerHTML += "l"; 
document.body.innerHTML += "d"; 
document.body.innerHTML += "!"; 
} 
Concurrent.Thread.create(hello); 
</script> 
</body> 
</html>
ログイン後にコピー


著者 真木 大介 翻訳者 張 凱峰
AJAX テクノロジを使用して開発される Web サイトはますます増えていますが、複雑な AJAX アプリケーションを構築するのは困難です。まだ難しい問題です。これらの困難の主な理由は何ですか?サーバーとの非同期通信の問題でしょうか?それとも GUI プログラミングの問題でしょうか?通常、これら 2 つのタスクはデスクトップ プログラムによって実行されますが、同じ機能を実現できる AJAX アプリケーションを開発するのがなぜそれほど難しいのでしょうか?
AJAX 開発の難しさ
簡単な例を通してこの問題を理解してみましょう。サーバーからすべての記事情報を一度にロードするのではなく、ユーザーのリクエストに応じてサーバーと対話し、各記事の情報を動的にロードできるツリー構造の掲示板システム (BBS) を構築するとします。各記事には、システム内で一意の識別子として使用できる ID、投稿者の名前、記事の内容、およびすべてのサブ記事の ID を含む配列情報の 4 つの関連属性があります。まず、記事情報をロードできる getArticle() という関数があるとします。この関数が受け取るパラメータはロードする記事のIDであり、これを介してサーバーから記事情報を取得できます。返されるオブジェクトには、記事に関連する 4 つの属性 (id、name、content、children) が含まれます。ルーチンは次のとおりです。

function ( id ) { 
var a = getArticle(id); 
document.writeln(a.name + " 
" + a.content); 
}
ログイン後にコピー

ただし、同じ記事 ID でこの関数を繰り返し呼び出すと、サーバーとの無駄な通信が繰り返し必要になることに気づくかもしれません。この問題を解決するには、キャッシュ機能を備えた getArticle() と同等の関数 getArticleWithCache() の使用を検討できます。この例では、getArticle() によって返されたデータはグローバル変数としてのみ保存されます:

var cache = {}; 
function getArticleWithCache ( id ) { 
if ( !cache[id] ) { 
cache[id] = getArticle(id); 
} 
return cache[id]; 
}
ログイン後にコピー

これで、読み取られた記事がキャッシュされたので、backgroundLoad() 関数を考えてみましょう。は、上で説明したキャッシュ メカニズムを使用してすべての記事情報をロードします。その目的は、読者が記事を読むときに、そのすべてのサブ記事をバックグラウンドからプリロードすることです。記事データはツリー構造になっているため、ツリーを走査してすべての記事をロードする再帰アルゴリズムを簡単に作成できます:

function backgroundLoad ( ids ) { 
for ( var i=0; i < ids.length; i++ ) { 
var a = getArticleWithCache(ids[i]); 
backgroundLoad(a.children); 
} 
}
ログイン後にコピー

backgroundLoad ()函数接收一个ID数组作为参数,然后通过每个ID调用前面定义过的getArticldWithCache()方法,这样就把每个ID对应的文章缓存起来。之后再通过已加载文章的子文章ID数组递归调用backgroundLoad()方法,如此整个文章树就被缓存起来。
到目前为止,一切似乎看起来都很完美。然而,只要你有过开发AJAX应用的经验,你就应该知晓这种幼稚的实现方法根本不会成功,这个例子成立的基础是默认 getArticle()用的是同步通信。可是,作为一条基本原则,JavaScript要求在与服务器进行交互时要用异步通信,因为它是单线程的。就简单性而言,把每一件事情(包括GUI事件和渲染)都放在一个线程里来处理是一个很好的程序模型,因为这样就无需再考虑线程同步这些复杂问题。另一方面,他也暴露了应用开发中的一个严重问题,单线程环境看起来对用户请求响应迅速,但是当线程忙于处理其它事情时(比如说调用getArticle()),就不能对用户的鼠标点击和键盘操作做出响应。
如果在这个单线程环境里进行同步通信会发生什么事情呢?同步通信会中断浏览器的执行直至获得通信结果。在等待通信结果的过程中,由于服务器的调用还没有完成,线程会停止响应用户并保持锁定状态直到调用返回。因为这个原因,当浏览器在等待服务器响应时它不能对用户行为作出响应,所以看起来像是冻结了。当执行 getArticleWithCache()和backgroundLoad()会有同样的问题,因为它们都是基于getArticle()函数的。由于下载所有的文章可能会耗费很可观的一段时间,因此对于backgroundLoad()函数来说,浏览器在此段时间内的冻结就是一个很严重的问题——既然浏览器都已经冻结,当用户正在阅读文章时就不可能首先去执行后台预加载数据,如果这样做连当前的文章都没办法读。
如上所述,既然同步通信在使用中会造成如此严重的问题,JavaScript就把异步通信作为一条基本原则。因此,我们可以基于异步通信改写上面的程序。 JavaScript要求以一种事件驱动的程序设计方式来写异步通信程序。在很多场合中,你都必须指定一个回调程序,一旦收到通信响应,这个函数就会被调用。例如,上面定义的getArticleWithCache()可以写成这样:

var cache = {}; 
function getArticleWithCache ( id, callback ) { 
if ( !cache[id] ) { 
callback(cache[id]); 
} else { 
getArticle(id, function( a ){ 
cache[id] = a; 
callback(a); 
}); 
} 
}
ログイン後にコピー


ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート