ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript 非同期プログラミング_JavaScript スキルの詳細な説明

JavaScript 非同期プログラミング_JavaScript スキルの詳細な説明

WBOY
WBOYオリジナル
2016-05-16 15:14:341021ブラウズ

非同期プログラミングによって引き起こされる問題は、クライアント側 Javascript では明らかではありませんが、サーバー側 Javascript がますます広く使用されるようになり、多数の非同期 IO 操作によってこの問題が明らかになります。この問題を解決するにはさまざまな方法があり、この記事ではその一部について説明しますが、詳しくは説明しません。誰もが自分の状況に応じて、自分に合った方法を選択する必要があります。

この記事では、js による非同期プログラミングについて詳しく紹介します。具体的な内容は次のとおりです。

1 非同期イベントについて

イベントは JavaScript の最も重要な機能であり、nodejs は js の非同期の性質を利用するように設計されています。ここでイベントのメカニズムについて説明しましょう。

js ファイルで特定の関数を実行する場合、foo() などの関数を直接呼び出す方法と、イベントを使用して関数を実行する方法があります。 setTimeout 関数や onready 属性に渡すなど、コールバック関数を呼び出します。

1. setTimeout 関数のイベントは非同期です
setTimeout は本質的に非同期イベントであり、遅延時間が経過するとトリガーされますが、場合によっては (実際にはほとんどの場合)、指定された遅延時間に従って実行されません。以下のコード

  var start = new Date();
  setTimeout(function() {
   console.log('settimeout1:',new Date()-start);
  }, 500);
  while (new Date() - start < 1000) {
   console.log('in while');
  }
  document.getElementById('test').addEventListener('click', function(){
   console.log('test:',new Date()-start);
  }, false)
  for(var i=0;i<10000;i++){
   console.log('in for');
  }
  setTimeout(function(){
   console.log('settimeout2: ',new Date()-start);
  },1000);
  /* 10214
  in while
  index.jsp (第 19 行)
  10000
  in for
  index.jsp (第 25 行)
  settimeout1: 2263
  index.jsp (第 16 行)
  settimeout2: 3239
  index.jsp (第 28 行)
  test: 10006
  index.jsp (第 22 行)
  test: 28175
  index.jsp (第 22 行)
  test: 28791
  index.jsp (第 22 行)
  test: 28966
  index.jsp (第 22 行) */

通常の理解では、遅延関数は 500 ミリ秒後に while ループを中断するはずですが、実際には中断されません。また、while ループおよび for ループ中に div をクリックしても、テストはすぐには出力されませんでした。説明は次のとおりです:

a) イベントキュー。 setTimeout 関数が呼び出されると、渡されたコールバック関数がイベント キューに追加され (イベントは初期化されてメモリ内にあります)、その後、コードが実行できなくなるまで後続のコードが実行され続けます (通常の実行フローではない) (イベント関数などの非同期コンテンツを除く)、適切なイベントがイベント キューからポップアウトされて実行されます。

b) js はシングルスレッドであり、スレッドがアイドル状態になるまでイベント ハンドラーは実行されません。

2 通常のイベントの非同期性は setTimeout
に似ています。
2 つの Promise オブジェクトと deferred オブジェクト

1.約束
Promise は、ajax などの非同期プログラミングにおける入れ子になったコールバック関数が多すぎると、コードがわかりにくくなり、特に nodejs では非同期が多用される問題の解決策です。さまざまなフレームワークが Promise を実装します。以下は jquery の Promise API です。

Promise の実装原則についてはここでは説明しません。この原則については別の章で説明します。

従来の Ajax 非同期プログラミングは次のように記述されます (jquery1.5 より前):

$.get('url', function(){
 $.get('url1', function(){
  $.get('url2', function(){

  }, 'json');
 }, 'json');
}, 'json');

このようなコードを書くと、開発と保守に大きな困難が生じます。幸いなことに、jquery1.5 が Promise を導入した後は、次のように書くことができます。

 $.ajax( "example.php" )
.done(function() { alert("success"); })
.fail(function() { alert("error"); })
.always(function() { alert("complete"); });

見た目は明らかにずっとシンプルになりました。

2.遅延オブジェクト

var nanowrimoing = $.Deferred();
var wordGoal = 5000;
nanowrimoing.progress(function(wordCount) {
var percentComplete = Math.floor(wordCount / wordGoal * 100);
$('#indicator').text(percentComplete + '% complete');
});
nanowrimoing.done(function(){
$('#indicator').text('Good job!');
});

3. ワーカー オブジェクトとマルチスレッド

4. 非同期スクリプトの読み込み

1. ページ内の従来のスクリプトの位置
スクリプトは、ブロッキングとノンブロッキングの 2 つの大きなカテゴリに分類されます。ここでのブロッキングは、実行ブロッキングではなく、ロードブロッキングを指します。

<!DOCTYPE html>
<html>
<head>
<script src="headScript"></script>
<script defer src="deferredScript"></script>
</head>
<body>
 <script async defer src="chatWidget"></script>
 <script async defer src="asyncScript"></script>
</body>
</html>

コードの上記の部分は、ページ内のスクリプトの位置に関して比較的標準的なものです。 1. 従来の未変更の headScript は、ブラウザーが JavaScript を上から下に解釈して実行するため、この一部のスクリプト ファイルはブロックされます。が最初に実行され、実行が完了するまで DOM はレンダリングされませんが、head タグ内の CSS が読み込まれます。 2. defer 属性を持つスクリプトは DOM がレンダリングされると同時にロードされますが、残念ながら、すべてのブラウザーが defer 属性をサポートしているわけではないため、jquery (関数) が作成されます。 。 3. async 属性と defer 属性の両方が存在する場合、defer は async をオーバーライドしますが、async が単独で提供される場合、スクリプトは DOM レンダリング中にロードされて実行されます。

2. プログラム可能なスクリプトの読み込み
最初から js ファイルをページに導入せず、ユーザーの操作を通じて動的に js スクリプトを読み込む場合は、それらをプログラムで追加できます。

ブラウザがサーバー スクリプトを取得するには 2 つの方法があります。もう 1 つは、ブラウザがサポートするため、DOM に 3f1c4e4b6b16bbbd69b2ee476dc4f83a タグを挿入する方法です。 HTTP リクエストを生成し、リーク スコープを評価します。

var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.src = '/js/feature.js';
head.appendChild(script);
script.onload = function() {
// 现在可以调用脚本里定义的函数了
}

以上がこの記事の全内容です。js 非同期プログラミングを学ぶ皆さんのお役に立てれば幸いです。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。