Maison > Article > interface Web > Vous guide étape par étape pour comprendre la programmation asynchrone en JavaScript
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.
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.
$.ajax({ url: "www.xx.com/api", async: false, // true success: function(result) { console.log(result); }, });
// 异步批量更新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 }, });
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 :
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) {}
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 :
Regarder la télévision est une opération asynchrone, et le bruit de la bouilloire est une fonction de rappel.
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.
setTimeout(() => { console.log("log2"); }, 0); console.log("log1"); // ?? log1 log2
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.
|
Code asynchrone | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
<script></script> Code |
Demande réseau (Ajax) | Opération d'E/S | Timer (setTimeout, setInterval) | ||||||||
Opération de rendu | Promesse (puis) | ||||||||||
async/await |
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);Les défauts de la fonction de rappel sont également évidents, et il est facile de produire un enfer de 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); }, }); }, }); }
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); }); }
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); }Aperçu en ligne
宏任务(不着急) | 微任务(着急) |
---|---|
<script></script> 整体代码 |
Promise |
setTimeout/setInterval |
Macro tâches (pas pressées) | Micro tâches (pressées ) |
---|---|
<script></script> Code global |
Promesse |
setTimeout/setInterval |
执行顺序:
执行整体代码<script></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");
写出 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!