Comment démarrer rapidement avec VUE3.0 : Entrez dans l'apprentissage
Lorsque plusieurs contextes accèdent à SharedArrayBuffer, si des opérations sont effectuées sur le tampon en même temps, des problèmes de conflit de ressources peuvent survenir. L'API Atomics permet à plusieurs contextes de lire et d'écrire en toute sécurité un SharedArrayBuffer en forçant qu'une seule opération puisse être effectuée sur le tampon à la fois.
La nature des opérations atomiques exclut les optimisations (telles que la réorganisation des instructions) que le système d'exploitation ou le matériel informatique effectuerait normalement automatiquement. Les opérations atomiques rendent également impossible l'accès simultané à la mémoire. Si elles sont utilisées de manière inappropriée, elles peuvent ralentir l'exécution du programme. Pour cette raison, l'intention de conception initiale de l'API Atomics est de créer des programmes JavaScript multithread complexes basés sur un minimum mais stable. comportement atomique.
L'API Atomics fournit un ensemble de méthodes simples pour effectuer des opérations de modification sur place. Dans la spécification ECMA, ces méthodes sont définies comme des opérations AtomicReadModifyWrite. Sous le capot, ces méthodes lisent une valeur à partir d'un emplacement dans SharedArrayBuffer, effectuent des opérations arithmétiques et au niveau du bit, et enfin écrivent le résultat au même emplacement. La nature atomique de ces opérations signifie que les opérations de lecture, de modification et d'écriture décrites ci-dessus seront exécutées dans l'ordre et ne seront pas interrompues par d'autres threads.
//Créez un tampon de taille 1 let sharedArrayBuffer = new SharedArrayBuffer(1); //Créer Unit8Arraylet basé sur le tampon typedArray = new Unit8Array(sharedArrayBuffer); //Tous les ArrayBuffers sont initialisés à 0console.log(typedArray); //Unit8Array[0] //Effectuer une addition atomique de 10 à la valeur à l'index 0Atomics.add(typedArray,0,10); //Unit8Array[10] //Effectuer une soustraction atomique de 10 sur la valeur à l'index 0Atomics.sub(typedArray,0,10); //Unit8Array[0]
Le compilateur JavaScript du navigateur et l'architecture du processeur elle-même ont le pouvoir de réorganiser les instructions pour améliorer l'efficacité de l'exécution du programme. Dans des circonstances normales, l'environnement monothread de JavaScript peut effectuer cette optimisation à tout moment, mais le réarrangement des instructions dans plusieurs threads peut entraîner des conflits de ressources et est extrêmement difficile à dépanner.
L'API Atomics résout ce problème de deux manières principales :
L'ordre de toutes les instructions atomiques les unes par rapport aux autres n'est jamais réorganisé.
L'utilisation de lectures ou d'écritures atomiques garantit que toutes les instructions ne sont pas réorganisées par rapport aux lectures et écritures atomiques.
En plus de lire et d'écrire des valeurs de tampon, Atomics.load() et Atomics.store() peuvent également créer des « barrières de code ». Le moteur JavaScript garantit que les instructions non atomiques peuvent être réorganisées localement par rapport à load() et store(), mais ce réarrangement ne violera pas les limites des lectures et écritures atomiques.
const sharedArrayBuffer = new SharedArrayBuffer(4); const view = nouveau Unit32Array (sharedArrayBuffer); //Effectuer une vue d'écriture non atomique[0] = 1; // L'écriture non atomique peut être garantie avant cette opération de lecture, donc 1console.log(Atomics.load(view,0)); //1 //Effectuer une écriture atomique Atomics.store(view,0,2); //La lecture non atomique peut être garantie une fois l'écriture atomique terminée, et 2console.log(view[0]); //2
Afin d'assurer une lecture continue et ininterrompue d'abord puis une écriture, l'API Atomics propose deux méthodes : Exchange() et compareExchange(). Atomics.exchange() effectue un échange simple qui garantit que les autres threads n'interrompront pas l'échange.
const sharedArrayBuffer = new SharedArrayBuffer(4); const view = nouveau Unit32Array (sharedArrayBuffer); //Écrivez 10Atomics.store(view,0,10) à l'index 0 ; //Lisez la valeur de l'index 0 et écrivez 5 à l'index 0console.log(Atomics.exchange(view,0,5)); //10 //Lire la valeur de l'index 0 console.log(Atomics.load(view,0)); //5
Dans un programme multithread, un thread peut vouloir écrire dans un tampon partagé uniquement si aucun autre thread n'a modifié la valeur depuis la dernière fois qu'elle a été lue. Si la valeur n'a pas été modifiée, ce thread peut écrire en toute sécurité la valeur mise à jour : si la valeur a été modifiée, effectuer une opération d'écriture détruira la valeur calculée par les autres threads. Pour ce type de tâche, l'API Atomics fournit la méthode compare-Exchange(). Cette méthode effectue l'opération d'écriture uniquement si la valeur à l'index cible correspond à la valeur attendue.
Sans une sorte de mécanisme de verrouillage, les programmes multithread ne peuvent pas prendre en charge des exigences complexes. À cette fin, l'API Atomics fournit des méthodes qui imitent Linux Futex (mutex rapide de l'espace utilisateur). Ces méthodes, bien que très simples en elles-mêmes, peuvent servir de composants de base pour des mécanismes de verrouillage plus complexes.
Toutes les opérations atomiques Futex ne peuvent être utilisées que sur les vues Int32Array, et de plus, uniquement dans les threads de travail.
La messagerie inter-documents, parfois également appelée XDM (messagerie inter-documents), est la capacité de transférer des informations entre différents contextes d'exécution (tels que différents threads de travail ou pages provenant de différentes sources).
L'API d'encodage est principalement utilisée pour convertir entre des chaînes et des tableaux stéréotypés.
L'API de fichier est toujours basée sur le champ de saisie du fichier dans le formulaire, mais ajoute la possibilité d'accéder directement aux informations du fichier. HTML5 ajoute une collection de fichiers au DOM pour les éléments d'entrée de fichiers. Lorsque l'utilisateur sélectionne un ou plusieurs fichiers dans le champ Fichier, la collection de fichiers contient un ensemble d'objets Fichier représentant les fichiers sélectionnés. Chaque objet Fichier possède des attributs en lecture seule.
Le type FileReader représente un mécanisme de lecture de fichiers asynchrone Vous pouvez considérer FileReader comme similaire à XMLHttpRequest, sauf qu'il est utilisé pour lire des fichiers à partir du système de fichiers au lieu de lire des données à partir du serveur. Le type FileReader propose plusieurs méthodes pour lire les données des fichiers.
readAsText(file,encoding);//Lire le contenu en texte brut du fichier et l'enregistrer dans l'attribut de résultat
readAsDataURL(file);//Lire le fichier et enregistrer l'URI des données du contenu dans l'attribut de résultat
readAsBinaryString(file); //Lire le fichier et enregistrer les données binaires de chaque caractère dans l'attribut result
readAsArrayBuffer(file); //Lire le fichier et enregistrer le contenu du fichier dans l'attribut result sous la forme d'ArrayBuffer
Une version synchrone du Type de lecteur de fichiers.
Dans certains cas, vous devrez peut-être lire une partie du fichier au lieu du fichier entier. Pour cela, l'objet File fournit une méthode appelée slice(). La méthode slice() reçoit deux paramètres : l'octet de départ et le nombre d'octets dans la zone Yaodu. Cette méthode renvoie une instance de Blob, qui est en fait une superclasse de File.
Blob représente un gros objet binaire, qui est le type d'encapsulation de JavaScript pour les données binaires non modifiables. Des tableaux contenant des chaînes, des ArrayBuffers, des ArrayBufferViews et même d'autres blobs peuvent être utilisés pour créer des blobs. Le constructeur Blob peut recevoir un paramètre options et y spécifier le type MIME.
L'API Streams est née pour résoudre un problème simple mais fondamental : comment une application Web consomme-t-elle de petits blocs d'informations ordonnés au lieu de gros blocs d'informations ? Il existe deux principaux scénarios d'application pour cette fonctionnalité.
L'API Streams définit trois flux :
Flux lisible : un flux qui peut lire des blocs de données via une interface publique. Les données entrent dans le flux en interne à partir de la source sous-jacente et sont ensuite traitées par le consommateur.
Flux inscriptible : flux dans lequel des blocs de données peuvent être écrits via une interface publique. Le producteur (consommateur) écrit des données dans le flux et les données sont transférées en interne vers l'emplacement de données sous-jacent (puits).
Flux de conversion : il se compose de deux flux, le flux inscriptible est utilisé pour recevoir des données et le flux lisible est utilisé pour générer des données. Ces deux contrôles de qualité du flux sont des transformateurs qui peuvent inspecter et modifier le contenu du flux selon les besoins.
L'API de cryptographie Web décrit un ensemble d'outils de cryptographie qui standardise la manière dont JavaScript implémente le cryptage de manière sécurisée et conventionnelle. Ces outils incluent la génération, l'utilisation et l'application de paires de clés cryptographiques, le cryptage et le déchiffrement des informations et la génération fiable de nombres aléatoires.
De nombreuses personnes utilisent Math.random()
lorsqu'elles ont besoin de générer des nombres aléatoires. Cette méthode est implémentée dans le navigateur en tant que générateur de nombres pseudo-aléatoires (PRNG, PseudoRandom Number Generator). Le soi-disant pseudo fait référence au processus de génération de valeurs qui n'est pas vraiment aléatoire. Les valeurs générées par PRNG ne simulent que des caractéristiques aléatoires. Le PRNG du navigateur n'utilise pas de véritable source aléatoire, mais applique uniquement un algorithme fixe à un état interne. Chaque fois que Math.random()
est appelé, cet état interne est modifié par un algorithme, et le résultat est converti en un nouveau nombre aléatoire. Par exemple, le moteur V8 utilise un algorithme appelé xorshift128+
pour effectuer cette modification.
Étant donné que l'algorithme lui-même est fixe et que son entrée est uniquement l'état précédent, la séquence de nombres aléatoires est également déterminée. xorshift128+
utilise un état interne de 128 bits et l'algorithme est conçu de telle sorte que tout état initial génère 2 128 -1 valeurs pseudo-aléatoires avant de se répéter. Ce type de boucle est appelé boucle de permutation et la longueur de cette boucle est appelée période. Il est évident que si l’attaquant connaît l’état interne du PRNG, il peut prédire les valeurs pseudo-aléatoires générées par la suite. Si le développeur utilise par inadvertance PRNG pour générer une clé privée à des fins de chiffrement, l'attaquant peut utiliser cette fonctionnalité de PRNG pour calculer la clé privée.
Les générateurs de nombres pseudo-aléatoires sont principalement utilisés pour calculer rapidement des nombres apparemment aléatoires, mais ne conviennent pas aux algorithmes de cryptage. Pour résoudre ce problème, un générateur de nombres pseudo-aléatoires cryptographiquement sécurisé (CSPRNG, Cryptographically Secure PseudoRandom Number Generator), ajoute en outre une entropie comme. entrée, comme le test du temps matériel ou d'autres caractéristiques du système avec un comportement imprévisible, bien que pas aussi rapide que PRNG, la valeur générée est plus difficile à prédire et peut être utilisée pour le cryptage.
L'API Web Cryptography introduit CSPRNG, accessible sur l'objet Crypto
global via crypto.getRandomValues()
. Contrairement à Math.random()
qui renvoie un nombre à virgule flottante compris entre 0 et 1, getRandomValues()
écrit des valeurs aléatoires dans le tableau stéréotypé qui lui est passé en paramètre. La classe du tableau stéréotypé n'a pas d'importance car le tampon sous-jacent sera rempli de bits aléatoires.