Dans l'article précédent "Une brève analyse du problème du cache d'entrée dans Vue (partage de code)", je vous ai présenté le problème du cache d'entrée dans Vue. L'article suivant vous présentera l'implémentation des files d'attente dans js. Jetons un coup d'œil.
La file d'attente (File d'attente
) est une sorte de premier entré, premier sorti (Premier entré
, premier sorti code> En abrégé <code>FIFO
) principe de collecte ordonnée. La différence entre cela et une pile est que la pile est premier entré, premier sorti et la file d'attente est première entrée, premier sorti. La pile entre et sort à une extrémité, tandis que la file d'attente entre et sort à une extrémité. L'opération de suppression de la pile est effectuée en fin de table, et l'opération de suppression de la file d'attente est effectuée en tête de table. La pile séquentielle peut réaliser un partage d'espace multi-pile, mais pas la file d'attente séquentielle. Le dénominateur commun est que seules l’insertion et la suppression d’éléments sont autorisées aux points finaux. Les modes de gestion des piles multi-chaînes et des files d'attente multi-chaînes peuvent être les mêmes. Queue
)是一种遵从先进先出(First in
,first out
。简称FIFO
)原则的有序集合。 它和栈的不同点是栈是先进后出的,队列是先进先出的,栈都是在一端进与出,而队列是在一端进在另一端出。栈的删除操作在表尾进行,队列的删除操作在表头进行。顺序栈能够实现多栈空间共享,而顺序队列不能。 共同点是只允许在端点处插入和删除元素。多链栈和多链队列的管理模式可以相同。
JavaScript
是单线程语言,主线程执行同步代码。 函数调用时, 便会在内存形成了一个“调用记录”,又称“调用帧”,保存调用位置和内部变量等信息。如果函数内部还调用了其他函数,那么在调用记录上方又会形成一个调用记录, 所有的调用记录就形成一个“调用栈”。(尾调用、尾递归优化)
对象被分配在一个堆中,一个用以表示一个内存中大的未被组织的区域。
JS
是单线程, 主线程执行同步代码, 事件、I/O 操作等异步任务,将会进入任务队列执行,异步执行有结果之后,就会变为等待状态, 形成一个先进先出的执行栈,主线程的同步代码执行完之后,再从”任务队列”中读取事件, 执行事件异步任务的回调。 这就是为什么执行顺序是, 同步 > 异步 > 回调 更简单的说:只要主线程空了(同步),就会去读取”任务队列”(异步),这就是JavaScript
的运行机制。
本文将实现 基本队列、优先队列和循环队列
消息队列与事件循环Event Loop
一个JavaScript
运行时包含了一个待处理的消息队列(异步任务),(内部是不进入主线程,而进入”任务队列”(task queue
)的任务。比如UI
事件、ajax
网络请求、定时器setTimeout
和setInterval
等。 每一个消息都与一个函数(回调函数callback
JavaScript
est un langage à thread unique et le thread principal exécute du code synchrone. Lorsqu'une fonction est appelée, un « enregistrement d'appel », également appelé « trame d'appel », est formé dans la mémoire pour enregistrer des informations telles que l'emplacement de l'appel et les variables internes. Si d'autres fonctions sont appelées dans la fonction, un autre enregistrement d'appel sera formé au-dessus de l'enregistrement d'appel, et tous les enregistrements d'appel forment une « pile d'appels ». (Appel de queue, optimisation de la récursion de queue)
Les objets sont alloués dans un tas, une grande zone non organisée utilisée pour représenter une mémoire.
DoncJS
est un thread unique. Le thread principal exécute du code synchrone telles que les événements et les opérations d'E/S entreront dans la file d'attente des tâches pour exécution. il deviendra L'état d'attente forme une pile d'exécution premier entré, premier sorti.Une fois le code de synchronisation du thread principal exécuté, les événements sont lus dans la « file d'attente des tâches » et les rappels des tâches asynchrones d'événements sont exécutés. C'est pourquoi l'ordre d'exécution est synchrone>asynchrone>callback. Pour le dire plus simplement : tant que le thread principal est vide (synchrone), il lira la "file d'attente des tâches" (asynchrone). C'est du JavaScript).
Mécanisme de fonctionnement. Cet article implémentera la file d'attente de base, la file d'attente prioritaire et la file d'attente circulaire
File d'attente de messages et boucle d'événement
Boucle d'événementUn runtimeJavaScript
contient une file d'attente de messages en attente (Tâche asynchrone
), ( à l'intérieur se trouvent des tâches qui n'entrent pas dans le thread principal mais entrent dans la "file d'attente des tâches" (file d'attente des tâches
Par exemple, les événements UI
, ajax
). Requêtes réseau, timers setTimeout
et setInterval
, etc. Chaque message est associé à une fonction (fonction de rappel
callback
). Le message est supprimé de la file d'attente et traité. Ce processus consiste à appeler la fonction associée au message (et ainsi à créer un cadre de pile initial. Lorsque la pile est à nouveau vide, cela signifie que le message est traité. Ce processus est terminé. est continu, donc l'ensemble du mécanisme de fonctionnement est également appelé Event Loop (Event Loop
)Basic Queue
La méthode de file d'attente de base comprend les 6 méthodes suivantes
① Ajouter des éléments à la file d'attente (queue) (mise en file d'attente. ) ② (depuis la tête de file d'attente) supprimer des éléments (dequeue) ③ Vérifier les éléments en tête de file d'attente (avant)④ Vérifier si la file d'attente est vide (isEmpty )
⑤ Afficher la file d'attente longueur (taille) 🎜🎜⑥ Afficher la file d'attente (imprimer) 🎜function Queue() { //初始化队列(使用数组实现) var items = []; //入队 this.enqueue = function (ele) { items.push(ele); }; //出队 this.dequeue = function () { return items.shift(); }; //返回首元素 this.front = function () { return items[0]; }; //队列是否为空 this.isEmpty = function () { return items.length == 0; }; //清空队列 this.clear = function () { items = []; }; //返回队列长度 this.size = function () { return items.length; }; //查看列队 this.show = function () { return items; }; } var queue = new Queue(); queue.enqueue("hello"); queue.enqueue("world"); queue.enqueue("css"); queue.enqueue("javascript"); queue.enqueue("node.js"); console.log(queue.isEmpty()); // false console.log(queue.show()); //hello,world,css3,javascript,node.js console.log(queue.size()); //5 console.log(queue.front()); //hello console.log(queue.dequeue()); //hello console.log(queue.show()); //'world', 'css', 'javascript', 'node.js' console.log(queue.clear()); console.log(queue.size()); //0
function PriorityQueue() { //初始化队列(使用数组实现) var items = [] //因为存在优先级,所以插入的列队应该有一个优先级属性 function queueEle(ele, priority) { this.ele = ele this.priority = priority } //入队 this.enqueue = function (ele, priority) { let element = new queueEle(ele, priority) //为空直接入队 if (this.isEmpty()) { items.push(element) } else { var qeueued = false; //是否满足优先级要求,并且已经入队 for (let i = 0; i < this.size(); i++) { if (element.priority < items[i].priority) { items.splice(i, 0, element) qeueued = true break; } } //如果不满足要求,没有按要求入队,那么就直接从尾部入队 if (!qeueued) items.push(element) } } //出队 this.dequeue = function () { return items.shift() } //返回首元素 this.front = function () { return items[0] } //队列是否为空 this.isEmpty = function () { return items.length == 0 } //清空队列 this.clear = function () { items = [] } //返回队列长度 this.size = function () { return items.length } //查看列队 this.show = function () { return items } } var priorityQueue = new PriorityQueue(); priorityQueue.enqueue('优先级2-1', 2); priorityQueue.enqueue('优先级1-1', 1); priorityQueue.enqueue('优先级1-2', 1); priorityQueue.enqueue('优先级3-1', 3); priorityQueue.enqueue('优先级2-2', 2); priorityQueue.enqueue('优先级1-3', 1); priorityQueue.show(); // 按优先级顺序输出 //输出 [ 0:queueEle {ele: "优先级1-1", priority: 1}, 1:queueEle {ele: "优先级1-2", priority: 1}, 2:queueEle {ele: "优先级1-3", priority: 1}, 3:queueEle {ele: "优先级2-1", priority: 2}, 4:queueEle {ele: "优先级2-2", priority: 2}, 5:queueEle {ele: "优先级3-1", priority: 3} ]
function Queue() { //初始化队列(使用数组实现) var items = []; //入队 this.enqueue = function (ele) { items.push(ele); }; //出队 this.dequeue = function () { return items.shift(); }; //返回首元素 this.front = function () { return items[0]; }; //队列是否为空 this.isEmpty = function () { return items.length == 0; }; //清空队列 this.clear = function () { items = []; }; //返回队列长度 this.size = function () { return items.length; }; //查看列队 this.show = function () { return items; }; } /** * * @param {名单} names * @param {指定传递次数} num */ function onlyOne(names, num) { var queue = new Queue(); //所有名单入队 names.forEach((name) => { queue.enqueue(name); }); //淘汰的人名 var loser = ""; //只要还有一个以上的人在,就一直持续 while (queue.size() > 1) { for (let i = 0; i < num; i++) { //把每次出队的人,再次入队 ,这样一共循环了num 次(击鼓传花一共传了num次) queue.enqueue(queue.dequeue()); } //到这就次数就用完了,下一个就要出队了 loser = queue.dequeue(); console.log(loser + "被淘汰了"); } //到这就剩下一个人了 return queue.dequeue(); } var names = ["文科", "张凡", "覃军", "邱秋", "黄景"]; var winner = onlyOne(names, 99); console.log("金马奖影帝最终获得者是:" + winner);
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!