recherche
Maisoninterface Webjs tutorielExplication détaillée du code d'implémentation de l'exécution asynchrone de la fonction JavaScript

Supposons que vous ayez plusieurs fonctions fn1, fn2 et fn3 qui doivent être appelées dans l'ordre. La manière la plus simple est bien sûr :


fn1();
fn2();
fn3();
<.> Mais parfois, ces fonctions sont ajoutées une par une pendant l'exécution, et vous ne savez pas quelles fonctions sont là lorsque vous les appelez. À ce stade, vous pouvez prédéfinir un tableau, y insérer les fonctions lors de l'ajout des fonctions. , et sélectionnez-les dans l'ordre dans le tableau si nécessaire, sortez-les un par un et appelez-les un par un :



var stack = [];
// 执行其他操作,定义fn1
stack.push(fn1);
// 执行其他操作,定义fn2、fn3
stack.push(fn2, fn3);
// 调用的时候
stack.forEach(function(fn) { fn() });
Ce n'est pas le cas. peu importe que la fonction ait un nom ou non. Vous pouvez également transmettre directement la fonction anonyme. Testons-le :



var stack = [];
function fn1() {
  console.log(&#39;第一个调用&#39;);
}
stack.push(fn1);

function fn2() {
  console.log(&#39;第二个调用&#39;);
}
stack.push(fn2, function() { console.log(&#39;第三个调用&#39;) });

stack.forEach(function(fn) { fn() }); // 按顺序输出&#39;第一个调用&#39;、&#39;第二个调用&#39;、&#39;第三个调用&#39;
Cette implémentation fonctionne bien jusqu'à présent, mais nous avons ignoré une situation, qui est l'appel de fonctions asynchrones. L'asynchronie est un sujet incontournable en JavaScript. Je ne vais pas aborder ici les différents termes et concepts liés à l'asynchrone en JavaScript. Les lecteurs sont invités à le vérifier par eux-mêmes (comme un commentaire célèbre). Si vous savez que le code suivant affichera 1, 3 et 2, continuez à lire :



console.log(1);

setTimeout(function() {
  console.log(2);
}, 0);

console.log(3);
S'il y a une fonction dans la pile file d'attente : Notre implémentation de fonctions asynchrones similaires est foirée :



var stack = [];

function fn1() { console.log(&#39;第一个调用&#39;) };
stack.push(fn1);

function fn2() {
  setTimeout(function fn2Timeout() {
     console.log(&#39;第二个调用&#39;);
  }, 0);
}
stack.push(fn2, function() { console.log(&#39;第三个调用&#39;) });

stack.forEach(function(fn) { fn() }); // 输出&#39;第一个调用&#39;、&#39;第三个调用&#39;、&#39;第二个调用&#39;
Le problème est évident, fn2 est bien appelé dans l'ordre, mais la fonction fn2Timeout dans setTimeout () { console.log('Second call') } n'est pas exécuté immédiatement (même si le délai d'attente est défini sur 0) ; fn2 revient immédiatement après l'appel, puis exécute fn3. Après l'exécution de fn3, c'est vraiment le tour de fn2Timeout. .


Comment le résoudre ? Analysons-le. La clé ici est fn2Timeout. Nous devons attendre qu'il soit réellement exécuté avant d'appeler fn3. Idéalement, cela ressemble à ceci :



function fn2() {
  setTimeout(function() {
    fn2Timeout();
    fn3();
  }, 0);
}
. Mais cela équivaut à supprimer le fn2Timeout d'origine et à le remplacer par une nouvelle fonction, puis à insérer les fn2Timeout et fn3 d'origine. Cette méthode de modification dynamique de la fonction d'origine porte un terme spécial appelé Monkey Patch. Selon le mantra de nos programmeurs : "Cela peut certainement être fait", mais c'est un peu délicat à écrire, et il est facile de s'impliquer. Existe-t-il une meilleure façon ?

Nous prenons du recul et n'insistons pas pour attendre que fn2Timeout soit complètement exécuté avant d'exécuter fn3. Au lieu de cela, nous l'appelons sur la dernière ligne du corps de la fonction fn2Timeout :


Cela semble mieux, mais lorsque fn2 a été défini, il n'y avait pas encore de fn3. D'où vient fn3 ?
function fn2() {
  setTimeout(function fn2Timeout() {
    console.log(&#39;第二个调用&#39;);
    fn3();    // 注{1}
  }, 0);
}

Il y a un autre problème. Puisque fn3 doit être appelé dans fn2, nous ne pouvons pas appeler fn3 via stack.forEach, sinon fn3 sera appelé deux fois.

Nous ne pouvons pas écrire fn3 dans fn2. Au lieu de cela, il nous suffit de trouver la fonction suivante de fn2 dans la pile à la fin de fn2Timeout, puis d'appeler :



Cette fonction suivante est responsable de trouver la pile et d’exécuter la fonction suivante qu’elle contient. Implémentons ensuite maintenant :
function fn2() {
  setTimeout(function fn2Timeout() {
    console.log(&#39;第二个调用&#39;);
    next();
  }, 0);
}



next utilise stack[index] pour obtenir la fonction dans la pile. L'index augmentera de 1 à chaque fois que next est. appelé, donc Pour atteindre l'objectif de supprimer la fonction suivante.
var index = 0;

function next() {
  var fn = stack[index];
  index = index + 1; // 其实也可以用shift 把fn 拿出来
  if (typeof fn === &#39;function&#39;) fn();
}
next est utilisé comme ceci :




Maintenant que la ligne stack.forEach a été supprimée, nous appelons next par nous-mêmes, et next le fera découvrir ce qu'il y a dans la pile La première fonction fn1 est exécutée, next est appelée dans fn1 pour trouver la fonction suivante fn2 et exécutée, puis next est appelée dans fn2, et ainsi de suite.
var stack = [];

// 定义index 和next

function fn1() {
  console.log(&#39;第一个调用&#39;);
  next(); // stack 中每一个函数都必须调用`next`
};
stack.push(fn1);

function fn2() {
  setTimeout(function fn2Timeout() {
     console.log(&#39;第二个调用&#39;);
     next(); // 调用`next`
  }, 0);
}
stack.push(fn2, function() {
  console.log(&#39;第三个调用&#39;);
  next(); // 最后一个可以不调用,调用也没用。
});

next(); // 调用next,最终按顺序输出&#39;第一个调用&#39;、&#39;第二个调用&#39;、&#39;第三个调用&#39;。
Chaque fonction doit appeler next. Si elle n'est pas écrite dans une certaine fonction, le programme se terminera directement après l'exécution de la fonction sans aucun mécanisme pour continuer.


Après avoir compris cette implémentation de la file d'attente des fonctions, vous devriez être capable de résoudre la question d'entretien suivante :



Node.js This C'est ainsi que le célèbre framework de connexion de Zhongda implémente les files d'attente middleware.
// 实现一个LazyMan,可以按照以下方式调用:
LazyMan(“Hank”)
/* 输出: 
Hi! This is Hank!
*/

LazyMan(“Hank”).sleep(10).eat(“dinner”)输出
/* 输出: 
Hi! This is Hank!
// 等待10秒..
Wake up after 10
Eat dinner~
*/

LazyMan(“Hank”).eat(“dinner”).eat(“supper”)
/* 输出: 
Hi This is Hank!
Eat dinner~
Eat supper~
*/

LazyMan(“Hank”).sleepFirst(5).eat(“supper”)
/* 等待5秒,输出
Wake up after 5
Hi This is Hank!
Eat supper
*/

// 以此类推。


Si vous faites attention, vous verrez peut-être que ce next ne peut être placé qu'à la fin de la fonction pour le moment. S'il est placé au milieu, le problème d'origine se produira toujours :



Grâce à différentes implémentations, redux et koa peuvent se placer ensuite au milieu de la fonction. Après avoir exécuté les fonctions suivantes, il peut ensuite être rétabli. pour exécuter ensuite le code ci-dessous, ce qui est très intelligent. Écrivez à nouveau quand vous aurez le temps.
function fn() {
  console.log(1);
  next();
  console.log(2); // next()如果调用了异步函数,console.log(2)就会先执行
}

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!

Déclaration
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
Comprendre le moteur JavaScript: détails de l'implémentationComprendre le moteur JavaScript: détails de l'implémentationApr 17, 2025 am 12:05 AM

Comprendre le fonctionnement du moteur JavaScript en interne est important pour les développeurs car il aide à écrire du code plus efficace et à comprendre les goulots d'étranglement des performances et les stratégies d'optimisation. 1) Le flux de travail du moteur comprend trois étapes: analyse, compilation et exécution; 2) Pendant le processus d'exécution, le moteur effectuera une optimisation dynamique, comme le cache en ligne et les classes cachées; 3) Les meilleures pratiques comprennent l'évitement des variables globales, l'optimisation des boucles, l'utilisation de const et de locations et d'éviter une utilisation excessive des fermetures.

Python vs JavaScript: la courbe d'apprentissage et la facilité d'utilisationPython vs JavaScript: la courbe d'apprentissage et la facilité d'utilisationApr 16, 2025 am 12:12 AM

Python convient plus aux débutants, avec une courbe d'apprentissage en douceur et une syntaxe concise; JavaScript convient au développement frontal, avec une courbe d'apprentissage abrupte et une syntaxe flexible. 1. La syntaxe Python est intuitive et adaptée à la science des données et au développement back-end. 2. JavaScript est flexible et largement utilisé dans la programmation frontale et côté serveur.

Python vs JavaScript: communauté, bibliothèques et ressourcesPython vs JavaScript: communauté, bibliothèques et ressourcesApr 15, 2025 am 12:16 AM

Python et JavaScript ont leurs propres avantages et inconvénients en termes de communauté, de bibliothèques et de ressources. 1) La communauté Python est amicale et adaptée aux débutants, mais les ressources de développement frontal ne sont pas aussi riches que JavaScript. 2) Python est puissant dans les bibliothèques de science des données et d'apprentissage automatique, tandis que JavaScript est meilleur dans les bibliothèques et les cadres de développement frontaux. 3) Les deux ont des ressources d'apprentissage riches, mais Python convient pour commencer par des documents officiels, tandis que JavaScript est meilleur avec MDNWEBDOCS. Le choix doit être basé sur les besoins du projet et les intérêts personnels.

De C / C à JavaScript: comment tout cela fonctionneDe C / C à JavaScript: comment tout cela fonctionneApr 14, 2025 am 12:05 AM

Le passage de C / C à JavaScript nécessite de s'adapter à la frappe dynamique, à la collecte des ordures et à la programmation asynchrone. 1) C / C est un langage dactylographié statiquement qui nécessite une gestion manuelle de la mémoire, tandis que JavaScript est dynamiquement typé et que la collecte des déchets est automatiquement traitée. 2) C / C doit être compilé en code machine, tandis que JavaScript est une langue interprétée. 3) JavaScript introduit des concepts tels que les fermetures, les chaînes de prototypes et la promesse, ce qui améliore la flexibilité et les capacités de programmation asynchrones.

Moteurs JavaScript: comparaison des implémentationsMoteurs JavaScript: comparaison des implémentationsApr 13, 2025 am 12:05 AM

Différents moteurs JavaScript ont des effets différents lors de l'analyse et de l'exécution du code JavaScript, car les principes d'implémentation et les stratégies d'optimisation de chaque moteur diffèrent. 1. Analyse lexicale: convertir le code source en unité lexicale. 2. Analyse de la grammaire: générer un arbre de syntaxe abstrait. 3. Optimisation et compilation: générer du code machine via le compilateur JIT. 4. Exécuter: Exécutez le code machine. Le moteur V8 optimise grâce à une compilation instantanée et à une classe cachée, SpiderMonkey utilise un système d'inférence de type, résultant en différentes performances de performances sur le même code.

Au-delà du navigateur: Javascript dans le monde réelAu-delà du navigateur: Javascript dans le monde réelApr 12, 2025 am 12:06 AM

Les applications de JavaScript dans le monde réel incluent la programmation côté serveur, le développement des applications mobiles et le contrôle de l'Internet des objets: 1. La programmation côté serveur est réalisée via Node.js, adaptée au traitement de demande élevé simultané. 2. Le développement d'applications mobiles est effectué par le reactnatif et prend en charge le déploiement multiplateforme. 3. Utilisé pour le contrôle des périphériques IoT via la bibliothèque Johnny-Five, adapté à l'interaction matérielle.

Construire une application SaaS multi-locataire avec next.js (intégration backend)Construire une application SaaS multi-locataire avec next.js (intégration backend)Apr 11, 2025 am 08:23 AM

J'ai construit une application SAAS multi-locataire fonctionnelle (une application EdTech) avec votre outil technologique quotidien et vous pouvez faire de même. Premièrement, qu'est-ce qu'une application SaaS multi-locataire? Les applications saas multi-locataires vous permettent de servir plusieurs clients à partir d'un chant

Comment construire une application SaaS multi-locataire avec Next.js (Frontend Integration)Comment construire une application SaaS multi-locataire avec Next.js (Frontend Integration)Apr 11, 2025 am 08:22 AM

Cet article démontre l'intégration frontale avec un backend sécurisé par permis, construisant une application fonctionnelle EdTech SaaS en utilisant Next.js. Le frontend récupère les autorisations des utilisateurs pour contrôler la visibilité de l'interface utilisateur et garantit que les demandes d'API adhèrent à la base de rôles

See all articles

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
1 Il y a quelques moisBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
1 Il y a quelques moisBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
1 Il y a quelques moisBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Commandes de chat et comment les utiliser
1 Il y a quelques moisBy尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Version crackée d'EditPlus en chinois

Version crackée d'EditPlus en chinois

Petite taille, coloration syntaxique, ne prend pas en charge la fonction d'invite de code

Version Mac de WebStorm

Version Mac de WebStorm

Outils de développement JavaScript utiles

Navigateur d'examen sécurisé

Navigateur d'examen sécurisé

Safe Exam Browser est un environnement de navigation sécurisé permettant de passer des examens en ligne en toute sécurité. Ce logiciel transforme n'importe quel ordinateur en poste de travail sécurisé. Il contrôle l'accès à n'importe quel utilitaire et empêche les étudiants d'utiliser des ressources non autorisées.

SublimeText3 version anglaise

SublimeText3 version anglaise

Recommandé : version Win, prend en charge les invites de code !

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP