Maison > interface Web > js tutoriel > Vous guide étape par étape pour comprendre la programmation asynchrone en JavaScript

Vous guide étape par étape pour comprendre la programmation asynchrone en JavaScript

青灯夜游
Libérer: 2021-06-18 09:50:18
avant
1417 Les gens l'ont consulté

Cet article vous présentera la programmation asynchrone en JavaScript. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. J'espère qu'il sera utile à tout le monde.

Vous guide étape par étape pour comprendre la programmation asynchrone en JavaScript

Asynchrone signifie asynchrone....

Cette section est peut-être un peu ennuyeuse, mais c'est un concept très important en JavaScript et très utile. est nécessaire d'apprendre.

Objectif

  • Améliorer l'efficacité du développement et écrire du code facile à maintenir

Introduction aux questions

  • Pourquoi la page reste-t-elle bloquée lors d'une demande ? ?
$.ajax({
  url: "www.xx.com/api",
  async: false, // true
  success: function(result) {
    console.log(result);
  },
});
Copier après la connexion
  • Pourquoi les données sont mises à jour mais pas le DOM ? ?
// 异步批量更新DOM(vue-nextTick)
// <p id="app">{{num}}</p>
new Vue({
  el: "#app",
  data: {
    num: 0,
  },
  mounted() {
    let dom = document.getElementById("app");
    while (this.num !== 100) {
      this.num++;
    }
    console.log("Vue num=" + this.num, "DOM num=" + dom.innerHTML);
    // Vue num=100,DOM num=0
    // nextTick or setTimeout
  },
});
Copier après la connexion

Raison de l'occurrence asynchrone

Raison : un seul thread (une seule chose est faite à un moment donné), le moteur JS du navigateur est unique- fileté causé.

Un seul thread signifie qu'il n'y a qu'un seul thread responsable de l'interprétation et de l'exécution du code IavaScript dans le moteur JS. Il pourrait tout aussi bien être appelé le thread principal.

Le soi-disant thread unique signifie qu'une seule tâche peut être accomplie à la fois. S'il y a plusieurs tâches, elles doivent être mises en file d'attente. La tâche précédente est terminée avant l'exécution de la tâche suivante.

Jetez d'abord un œil au schéma des threads du noyau du navigateur :

Vous guide étape par étape pour comprendre la programmation asynchrone en JavaScript

Parmi eux, le thread de rendu et le thread JS s'excluent mutuellement .

Supposons qu'il y ait deux fonctions, une de modification et une de suppression, exploitant un nœud DOM en même temps. S'il y a plusieurs threads, si les deux threads sont exécutés en même temps, il y aura certainement une impasse. et il y aura des problèmes.

La raison pour laquelle JS est conçu pour être monothread est due à l'environnement spécial du navigateur.

Avantages et inconvénients du single thread :

L'avantage de ce mode est qu'il est relativement simple à mettre en œuvre et l'environnement d'exécution est relativement simple L'inconvénient est que tant qu'il est effectué, une tâche prend beaucoup de temps, les tâches suivantes doivent être mises en file d'attente et attendues, ce qui retardera l'exécution de l'ensemble du programme. L'absence de réponse courante du navigateur (mort suspendue) est souvent causée par un certain morceau de code Javascript exécuté pendant une longue période (comme une boucle infinie), ce qui bloque la page entière à cet endroit et empêche d'autres tâches d'être effectuées.

Blocage courant (boucle infinie) :

while (true) {}
Copier après la connexion

JS a été conçu à l'origine pour être un langage de script qui s'exécute dans le navigateur, il ne voulait donc pas le rendre si compliqué, c'est pourquoi il a été conçu. Il est devenu un fil unique, c'est-à-dire que ne peut faire qu'une seule chose à la fois.

Afin de résoudre le blocage d'un seul threadcette lacune : l'asynchrone est généré.

Prenons l'exemple des nouilles instantanées :

  • Synchrone : Acheter des nouilles instantanées => Faire bouillir de l'eau (regarder) => Cuire des nouilles => Manger des nouilles instantanées
  • Asynchrone : Acheter des nouilles instantanées => Faire bouillir de l'eau (l'eau bout et la bouilloire sonnera - rappel) => Regarder la télévision => Cuire des nouilles (les nouilles sont prêtes et la bouilloire sonnera - rappel) => Regarder la télévision => Appelez-moi quand c'est fait => Mangez des nouilles instantanées

Regarder la télévision est une opération asynchrone, et le bruit de la bouilloire est une fonction de rappel.

Programmation asynchrone

La plupart du code dans JS est exécuté de manière synchrone, et seules quelques fonctions sont exécutées de manière asynchrone. Le code exécuté de manière asynchrone nécessite une programmation asynchrone.

Code asynchrone

setTimeout(() => {
  console.log("log2");
}, 0);
console.log("log1");
// ?? log1 log2
Copier après la connexion

Caractéristiques du code asynchrone : Il n'est pas exécuté immédiatement, mais doit attendre et être exécuté à un certain moment dans le futur.

< tr>
同步代码异步代码
<script>代码网络请求(Ajax)
I/O 操作定时器(setTimeout、setInterval)
渲染操作Promise(then)

async/await
Code synchrone

Code asynchrone
<script>CodeDemande réseau (Ajax)
Opération d'E/STimer (setTimeout, setInterval)
Opération de renduPromesse (puis) ​​< /td>
async/await

Fonction de rappel
  • La manière la plus courante d'écrire du code asynchrone consiste à utiliser des fonctions de rappel.
  • Requête réseau HTTP (l'opération xx est effectuée une fois la demande réussie et reconnue)
Mécanisme de liaison d'événement DOM (l'opération xx est effectuée après que l'utilisateur a déclenché l'événement)


Timer (setTimeout, setInterval) (Exécuter l'opération xx après avoir atteint l'heure définie)

// 注意到click方法中是一个函数而不是一个变量
// 它就是回调函数
$("#btn_1").click(function() {
  alert("Btn 1 Clicked");
});
// 或者
function click() {
  // 它就是回调函数
  alert("Btn 1 Clicked");
}
$("#btn_1").click(click);
Copier après la connexion
Vous guide étape par étape pour comprendre la programmation asynchrone en JavaScriptLes défauts de la fonction de rappel sont également évidents, et il est facile de produire un enfer de rappel :

  • Trois façons de programmation asynchrone
  • rappel
function getOneNews() {
  $.ajax({
    url: topicsUrl,
    success: function(res) {
      let id = res.data[0].id;
      $.ajax({
        url: topicOneUrl + id,
        success: function(ress) {
          console.log(ress);
          render(ress.data);
        },
      });
    },
  });
}
Copier après la connexion
  • promise
function getOneNews() {
  axios
    .get(topicsUrl)
    .then(function(response) {
      let id = response.data.data[0].id;
      return axios.get(topicOneUrl + id);
    })
    .then((res) => {
      render(res.data.data);
    })
    .catch(function(error) {
      console.log(error);
    });
}
Copier après la connexion

async/await

async function getOneNews() {
  let listData = await axios.get(topicsUrl);
  let id = listData.data.data[0].id;
  let data = await axios.get(topicOneUrl + id);
  render(data.data.data);
}
Copier après la connexion

Aperçu en ligne

Adresse d'aperçu : http://jsrun. net/s43Kp/embedded/all/ light

Une question ? ?

Si plusieurs codes asynchrones existent en même temps, quel doit être l'ordre d'exécution ? Lequel est exécuté en premier et lequel est exécuté plus tard ?

Macro-tâches et micro-tâches
宏任务(不着急)微任务(着急)
<script>整体代码Promise
setTimeout/setInterval
<🎜><🎜>Division du code asynchrone, le code asynchrone est divisé en macro-tâches et micro-tâches. <🎜>
<🎜>Macro tâches (pas pressées)<🎜><🎜>Micro tâches (pressées )<🎜>
<script>Code globalPromesse
setTimeout/setInterval<🎜>

事件循环(Event loop)

Vous guide étape par étape pour comprendre la programmation asynchrone en JavaScript

执行顺序:

  • 执行整体代码<script>(宏任务)

  • 执行所有微任务

  • 执行一个宏任务

  • 执行渲染线程

  • 2->3->2->3...依次循环(在 2、3 步中又创建了新的宏、微任务)

重复从宏任务和微任务队列里拿出任务去执行。

总结

因为浏览器设计的原因,JS 线程和渲染线程互斥,所以 JS 线程被设计成了单线程。

因为单线程执行一些操作(如网络请求)时有堵塞的问题,所有产生了异步。

因为有了异步,所以产生了异步编程,从而有了回调函数。

因为回调函数写多了会产生回调地狱,所有又有了解决回调地狱的 Promise 写法

自 ES7 标准后有了比 Promise 更加优雅的写法 ———— async/await 写法,也是异步编程的最终解决方法。

因为 JS 的代码分为同步和异步代码,同步代码的执行顺序不必多说,自上而下的执行。

但是如果有多个异步的代码,他的执行顺序又是怎么的呢??

为了解决多个异步代码的执行顺序问了,有了事件循环(EventLoop),将异步任务区分为宏任务、微任务,依据规则依次执行。

至此 完!

练习

console.log("script start");
setTimeout(function() {
  console.log("timeout1");
}, 10);
new Promise((resolve) => {
  console.log("promise1");
  resolve();
  setTimeout(() => console.log("timeout2"), 10);
}).then(function() {
  console.log("then1");
});
console.log("script end");
Copier après la connexion

写出 log 的输出结果,并说出理由。

更多编程相关知识,请访问:编程视频!!

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:segmentfault.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal