ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScriptの非同期とは何ですか?用途は何ですか?

JavaScriptの非同期とは何ですか?用途は何ですか?

不言
不言転載
2019-01-10 09:39:504785ブラウズ

この記事では、JavaScript の非同期とは何ですか?用途は何ですか?困っている友人は参考にしていただければ幸いです。

js 非同期とは何ですか?

JavaScript はシングルスレッドであることがわかっていますが、これはその目的に関係しています。ブラウザーのスクリプト言語としての JavaScript の主な目的は、ユーザーと対話して DOM を操作することです。これにより、シングルスレッドのみが可能であることが決まります。そうでない場合は、非常に複雑な同期の問題が発生します。たとえば、JavaScript に同時に 2 つのスレッドがあるとします。1 つのスレッドが特定の DOM ノードにコンテンツを追加し、もう 1 つのスレッドがそのノードを削除するとします。この場合、ブラウザーはどちらのスレッドを使用すればよいでしょうか。
いわゆる「シングル スレッド」とは、一度に 1 つのタスクのみを完了できることを意味します。複数のタスクがある場合は、それらをキューに入れる必要があり、前のタスクが完了したら、次のタスクが実行されます。
このモードの利点は、実装が比較的簡単で、実行環境が比較的シンプルであることです。欠点は、1 つのタスクに時間がかかると、後続のタスクをキューに入れる必要があり、実行が遅れることです。プログラム全体の。一般的なブラウザの応答不能 (サスペンドデス) は、特定の Javascript コードが長時間実行される (無限ループなど) ことが原因で発生することが多く、その結果、ページ全体がその場所でスタックし、他のタスクが実行できなくなります。
Ajax の同期リクエストはブラウザの UI (ボタン、メニュー、スクロール バーなど) をロックし、すべてのユーザー操作をブロックするため、ブラウザがフリーズします。jquery の Ajax にはこのような同期リクエスト関数を使用する必要があります。特に要求されるデータの量が多い場合には、同期要求の使用を避けてください。
非同期であると感じるために少しだけ注意してください
バックグラウンド インターフェイスは easy-mock を使用します。公式アドレス: https://easy-mock.com/
ajax は axios を使用します。基本的なコードは次のとおりです

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>javascript异步</title>
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>

<body>
  <button>点击</button>
  <script>
    {
      let myData = null
      //ajax请求
      function ajax() {
        axios.get('https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/mock')
          .then(data => {
            console.log("ajax返回成功");// handle success
            myData = data.data
            console.log(myData);

          })
          .catch(error => {
            // console.log(error); // handle error
            console.log("ajax返回失败");
          })
      }
    }
  </script>
</body>
</html>

いくつかの js を追加して効果を見てみましょう。

Asynchronous-Timer

      console.log(myData);
      setTimeout(() => {
        console.log('定时器');
      }, 2000);
      console.log(myData);

出力には、不安はありません

//null
//null
//定时器

実行順序:
最初の 1 つを最初に実行します console.log(myData);
その後、タイマーが発生し、タイマーが一時停止されます (つまり、タイマーは一時停止されます)
2 番目の console.log(myData);# を実行し続けます。 ##js コードは何も実行できません。戻って、中断されたタスクの実行を続行します。
次のチェストを見てください

Asynchronous-ajax

      console.log(myData);
      ajax()
      console.log(myData);

出力を見てください。まだサスペンスはありません

//null
//null
//ajax返回成功
//{success: true, data: {…}}(这是接口返回的数据,我们不必关心返回的具体内容,只要知道返回了就好,陌上寒注)
実行シーケンスは基本的に上記のタイマーと同様なので、ここでは詳しく説明しません。

2 つの栗を組み合わせて、

      console.log(myData);
      ajax()
      setTimeout(() => {
        console.log('定时器');
      }, 2000);
      console.log(myData);
の出力を見てみましょう。問題は見つかりましたか? 2 つの非同期関数が出会った場合、どちらが最初に実行されますか?より速く走った人が最初に処刑されますか?

これは実際、別の知識ポイントである

タスク キューとイベント ループにつながるとも言えます。

console.log(myData); は両方とも同期的に実行されます。どちらも js のメイン スレッドで実行されます。

メイン スレッドの外側にもタスク キューがあり、タスク キューには非同期で実行する必要があるコンテンツが格納されます。

メイン スレッドの実行が終了すると、タスク キューがクリアされるまで実行されます (継続的にスキャンを繰り返します)


このコードを確認してください

//null
//null
//ajax返回成功
//{success: true, data: {…}}
//定时器
出力: 1、3、2、説明することはありません

見てください。別のコード部分で

      console.log(1);
      setTimeout(function () {
        console.log(2);
      }, 1000);
      console.log(3);

出力: 2、1、これはなぜですか?
console.log(2); メインスレッドでは、最初に実行され、##setTimeout(function(){console.log(1);}, 0); # のみ タスク キューの内容は、メイン スレッドの実行が完了するまで実行されません。

メイン スレッドのタスクが実行された後、タスク キューの内容を継続的にスキャンする必要があるのはなぜですか?

このコードを見ると、理解するのに役立ちます

setTimeout(function(){console.log(1);}, 0);
console.log(2);
ボタン ボタンにクリック イベントを追加し、ブラウザが更新されている間ボタンをクリックし続けました (もちろん手動でクリックします)

出力を見てください:

      console.log(myData);
      ajax()
      setTimeout(() => {
        console.log('定时器');
      }, 2000);
      console.log(myData);
      const btn = document.querySelector('button')
      btn.onclick = () => {
        console.log("点击了");
      }

これで、メインスレッドがループでタスク キューをスキャンする理由が理解できますか?

イベント ループの各ラウンドはティックと呼ばれます (vue の nextTick を思い浮かべますか?)

ユーザー インタラクションが発生したとき (マウス クリック イベント、ページ スクロール イベント、ウィンドウ サイズ変更イベントなど)、ajax、タイマーやタイマーなどは、イベント ループ内のタスク キューにイベントを追加し、実行を待ちます。

フロントエンド非同期のシナリオは何ですか?



スケジュールされたタスク: setTimeout、setInverval

  1. ネットワーク リクエスト: Ajax リクエスト、img イメージの動的読み込み

  2. イベント バインディングまたは DOM イベント (クリック イベントなど)、いつクリックされたかはわかりませんが、クリックされる前にどうすればよいですか。 addEventListener でイベントの種類を登録すると、ブラウザにはこれを受け取るための別のモジュールがあり、イベントがトリガーされると、ブラウザの特定のモジュールが実行スタックに対応する関数を非同期キューにスローします。空の場合、この関数は直接実行されます。

  3. ES6 での約束

  4. 非同期が必要な場合:

待機が発生する可能性がある場合

    #待機中にアラートなどプログラムをブロックできない場合
  1. したがって、すべての「待機状況」は非同期である必要があります
  2. 一言で言えば、待機する必要があるがプログラムをブロックできない場合には、非同期
  3. を使用する必要があります。

    非同期と並列

    非同期と並列を混同しないでください。
    非同期はシングルスレッド、並列はマルチスレッドです
    非同期: メインスレッドのタスクは、メインスレッドのタスクが同期された後にのみ同期されます。実行が完了すると、タスク キュー内の非同期タスクは順番に実行されますか?
    Parallel: 2 つ以上のイベント チェーンが時間の経過とともに交互に実行されるため、より高いレベルからは同時に実行されているように見えます (ハンドルのみですが)。常に 1 つのイベント)

以上がJavaScriptの非同期とは何ですか?用途は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。