Scène et application de la manette des gaz anti - bavardage

sc ne et application la


Gros MIAOU..png

C'est le numéro. 117 Article original sans eau,Pour plus d'articles originaux,Cherchez le numéro public et suivez - nous~ Cet article a été publié pour la première fois sur le blog Zhengcai Cloud Front End:Scénario et application de la manette des gaz anti - bavardage

Scénario et application de la manette des gaz anti - bavardage

Contexte

Dans le développement quotidien,Nous rencontrons souvent des requêtes de recherche,L'utilisateur déclenche pendant le processus d'entrée Input Un changement de valeur qui déclenche continuellement un appel de fonction.Ou lorsque l'utilisateur glisse sur la page de recherche de l'article pour parcourir l'article,Si on écoutait le défilement de la fenêtre pour envoyer une demande de point d'enfouissement,Les appels d'interface sont souvent déclenchés.Mais parfois, nous ne voulons pas que l'utilisateur continue à fonctionner, Déclenche fréquemment des appels d'interface . Afin de limiter l'invocation de la fonction de déclenchement à haute fréquence à court terme , Nous pouvons utiliser des tampons et des étranglements .

Fonction anti - bavardage et étranglement, L'efficacité d'exécution de la fonction est optimisée en contrôlant la fréquence de déclenchement de l'événement. . Regardons d'abord la Convention visuellement à travers le diagramme ci - dessous. 、 Différence entre anti - secousses et étranglement . image-20210614222321441

L'abscisse dans le graphique est l'axe temporel , Vous pouvez voir que l'anti - bavardage effectue un rappel après que l'événement a cessé de se déclencher pendant un certain temps , L'étranglement consiste à effectuer un rappel à intervalles réguliers lorsque l'événement continue de se déclencher. .

Analyse de la scène de l'anti - tamponnage et de l'étranglement

Anti - secousses

Anti - secousses,Comme son nom l'indique,Prévenir les secousses. Utilisé pour convertir le déclenchement du comportement de l'utilisateur en déclenchement du comportement du programme , Empêcher le Jitter des résultats des actions de l'utilisateur .Pendant un certain temps, Événements à des intervalles que nous avons spécifiés n Exécution multiple en secondes , Le rappel n'est effectué qu'une seule fois .

Caractéristiques: Attendre qu'une opération s'arrête , Fonctionnement à intervalles réguliers

  • Déclenchement continu non exécuté
  • Ne pas déclencher avant un certain temps

Scénario d'application:

mousemove Événements de glissement de souris

// Ne pas exécuter immédiatement pour la première fois 
function debounce(func, wait) {
let timer;
return function () {
const context = this;
const args = arguments;
clearTimeout(timer);
timer = setTimeout(function(){
func.apply(context, args)
}, wait);
}
}
function getUserAction(e) {
// container Exemple de conteneur de code 
container.innerHTML = `${e.clientX},${e.clientY}`;
};
container.onmousemove = debounce(getUserAction, 1000);
Copier le Code

L'effet anti - bavardage n'est pas ajouté, comme le montre la figure. , Pendant le glissement de la souris ,x Et y Les coordonnées changent constamment. .

Après l'ajout de l'effet anti - bavardage, voir fig. , Lorsque la souris cesse de glisser 1000ms,x Et y Les coordonnées de l'axe sont mises à jour .

Ensuite, regardons un exemple que nous rencontrons souvent dans notre entreprise. ,Select Fonction de recherche dynamique côté serveur . La différence avec le scénario ci - dessus est de savoir s'il est exécuté pour la première fois.

// Exécuter la première fonction immédiatement , Afficher les valeurs par défaut pour l'utilisateur m Données, Attendre que l'entrée manuelle de l'utilisateur cesse de déclencher n Dans quelques secondes.,Encore une fois
function debounce(func, wait, immediate) {
let timer;
let localImmediate = immediate;
return function () {
const context = this;
const args = arguments;
if (localImmediate) {
// Marqué comme, Utilisé pour marquer si la première exécution est immédiate 
localImmediate = false;
func.apply(context, args);
}
clearTimeout(timer);
timer = setTimeout(function(){
func.apply(context, args)
}, wait);
}
}
function fetchData(vaule) {
// Appeler l'interface pour demander des données 
}
debounce(fetchData, n);
Copier le Code
  • L'entrée d'arrêt de l'utilisateur est réalisée par un tampon n Dans quelques secondes., Demander des données au serveur , Mais il est possible que l'utilisateur entre Hangzhou La première recherche a été déclenchée après . Puis il est entré. Gymnase municipal , Une deuxième recherche est déclenchée .

    Il peut y avoir deux situations affichées sur la page :

    • Le premier résultat de recherche est retourné plus rapidement que le deuxième , Sera affiché en premier Hangzhou Résultats de recherche pour, Re - show Hangzhou gymnase Résultats de recherche pour.L'effet est montré dans la figure:
    • Le premier résultat de recherche est retourné plus lentement que le deuxième , Sera affiché en premier Hangzhou gymnase Résultats de recherche pour, Re - show Hangzhou Résultats de recherche pour.L'effet est montré dans la figure:

    En fait, ni la première ni la deuxième situation ne sont bonnes. , Ce que nous espérons, c'est qu'il sera affiché directement une fois Hangzhou gymnase Résultats de recherche pour.

    Comment gérer ça? ? Nous pouvons simplement définir une variable pour marquer la dernière requête , Afficher les résultats retournés à l'utilisateur seulement si l'étiquette demandée par l'interface courante est égale à l'étiquette la plus récente .

/** * Chaque appel fetchData Méthodes, Mettre à jour les variables globales this.lastFetchId Et assigner des valeurs aux variables internes fetchId. * Chaque fetchData Logique interne de la méthode, Déterminer les variables internes après le retour réussi de l'interface fetchId Variable globale * this.lastFetchId égal ou non, Assigner si égal , Sinon, ne modifiez pas les données . */
// Variables globales, Marquer la dernière demande id,Chaque appel fetchData Mise à jour
this.lastFetchId = 0;
function fetchData(value) {
const { searchField, params = {}, url, dataKey } = this.props;
const [data, setData] = useState([]);
const [fetching, setFetching] = useState(false);
this.lastFetchId += 1;
// Variables internes par appel de méthode fetchId 
const fetchId = this.lastFetchId;
setData([]);
setFetching(true);
const postValue = typeof value === 'string' ? value : '';
params[searchField] = postValue;
request(url, {
method: 'post',
data: params,
}).then((res) => {
const { success, result } = res || {};
// Si ce n'est pas la dernière demande , Alors n'assignez pas de résultats 
if (fetchId !== this.lastFetchId) {
return;
}
if (success && Array.isArray(result)) {
setData(result);
setFetching(false);
}
});
};
Copier le Code

L'exemple ci - dessus montre que l'anti - bavardage évite de considérer une opération comme une opération multiple. , Limite supérieure de l'exécution de l'événement , C'est - à - dire après l'arrêt du déclenchement n Quelques secondes avant l'exécution . Dans le même scénario, il peut y avoir des opérations de soumission de formulaires telles que l'inscription, etc. l'utilisateur clique trop rapidement pour déclencher plusieurs demandes. 、 Éditeur de texte riche .

étranglement

étranglement,Comme son nom l'indique,Contrôle du débit. Utilisé par l'utilisateur pour contrôler la fréquence des événements lorsqu'il interagit avec la page , Un scénario général est une unit é de temps ou d'autres intervalles pour effectuer des opérations à intervalles réguliers. .Pendant un certain temps, Les événements arrivent à un intervalle que nous avons spécifié n Déclenché une fois par seconde .

Caractéristiques: Après chaque intervalle d'attente ,Exécution des opérations

  • Le déclenchement continu ne se produit pas plus d'une fois
  • Jusqu'à un certain temps / Autres intervalles ( Comme la hauteur de glissement )Et l'exécuter.

Scénario d'application ( Note:: Parce que l'exemple suivant concerne le contenu de l'entreprise , Pas de capture d'écran réelle ):

  • Scène du point d'enfouissement . Liste de recherche des articles 、 Vitrines, etc. , Lorsque l'utilisateur glisse Timing / Hauteur de glissement constante Envoyer une demande de point d'enfouissement
// Ne pas appliquer immédiatement ,In n Premier événement d'exécution en secondes , L'événement s'arrête et se déclenche à nouveau 
// Supposons que l'intervalle de temps fixé soit 1s,Si le 6.8s Stop trigger ,Alors, à la 6s Exécuter une fois,
// No 7s La dernière fois 
function throttle(func, wait) {
var timer;
return function() {
var context = this;
var args = arguments;
if (!timer) {
timer = setTimeout(function(){
timer = null;
func.apply(context, args)
}, wait)
}
}
}
function sendData(vaule) {
// Appeler l'interface pour envoyer les données 
}
throttle(sendData, n);
Copier le Code

Comme le montre la figure, Envoyer la demande de point d'enfouissement à intervalles réguliers

  • Lorsque le système o & M visualise le Journal d'exécution de l'application ,Chaque n Rafraîchir une fois par seconde
// Exécution immédiate,In n Premier événement d'exécution en secondes , L'événement s'arrêtera - t - il une fois déclenché? 
// Caractéristiques: Supposons que l'intervalle de temps fixé soit 1s,Si le 6.8s Stop trigger ,Alors, à la 6s Dernière exécution , Pas après. 
function throttle(func, wait) {
var previous = 0;
return function() {
// Conversion implicite
var now = +new Date();
var context = this;
var args = arguments;
if (now - previous > wait) {
previous = now;
func.apply(context, args);
}
}
}
function fetchLogData(vaule) {
// Appeler l'interface pour obtenir les données du Journal 
}
throttle(fetchLogData, n);
Copier le Code

Comme le montre la figure, Extraire le Journal d'exécution à intervalles réguliers

L'exemple ci - dessus montre la fréquence à laquelle les événements de contrôle des gaz sont déclenchés. , Limite à la fois les limites supérieure et inférieure de l'exécution de l'événement , C'est - à - dire chaque intervalle pendant le déclenchement de l'événement n Secondes à exécuter . Le même scénario pourrait avoir scroll mousemove Événements déclenchés plus fréquemment 、 Calcul de l'emplacement de la barre de progression du Navigateur 、input Recherche dynamique, etc. .

Lodash Analyse du code source de la manette des gaz anti - bavardage

La mise en œuvre de base et le scénario d'application de l'étranglement anti - bavardage sont décrits ci - dessus. , Facile à comprendre et à utiliser . Et le scénario d'affaires réel est utilisé , Nous choisissons plus de bibliothèques tierces matures pour obtenir des effets anti - tampons et d'étranglement .Actuellement, les LodashUnderscore.js Attendez.,Analysons - le. Lodash Réalisation de la méthode d'étranglement anti - bavardage fournie .

Anti - secousses:Lodash L'idée de base de la mise en œuvre de l'anti - bavardage est de ne pas gérer fréquemment les minuteurs , C'est ce qui s'est passé. shouldInvoke Pour déterminer si elle doit être exécutée func Fonctions, Uniquement disponible à l'extérieur cancel Le minuteur n'est annulé que lorsque la méthode annule le retard .

Le module d'exécution des fonctions décrit en détail ci - dessous. shouldInvoke Logique de mise en œuvre interne , Appelé dans le commutateur de minuterie et la fonction d'entrée pour déterminer si l'exécution doit être effectuée func Fonctions. Pour en savoir plus, consultez les commentaires suivants sur le code source. . Nous l'analysons en quatre modules :Définition de base、 Interrupteur de minuterie 、Exécution de la fonction、 Rappel externe .

Définitions de base ( Avec structure globale )

Voici Lodash Structure globale du Code pour la mise en œuvre de l'anti - bavardage , La fonction d'entrée définit certaines variables liées au minuteur et à l'exécution de la fonction .Total 10 Variables,Parmi eux maxWait、timerId、lastCallTime、lastInvokeTime、leading、maxing、trailing 7 Les variables dépendantes du temps sont un support important pour la mise en œuvre du commutateur de minuterie et du module d'exécution de la fonction .

import isObject from './isObject.js'
import root from './.internal/root.js'
function debounce(func, wait, options) {
/** ====== Définition de base ====== */
let lastArgs, // Dernière exécution debounced De arguments 
lastThis, // La dernière fois this 
maxWait, // Temps d'attente maximum, S'assurer qu'il est exécuté après un intervalle supérieur à l'intervalle maximal fixé , Utilisé pour obtenir un effet d'étranglement 
result, // Fonctions func Valeur de retour après exécution 
timerId, // Minuterie ID 
lastCallTime // Dernier appel debounce Le temps 
let lastInvokeTime = 0 // Dernière exécution func Le temps, Utilisé pour obtenir un effet d'étranglement 
let leading = false // Premier déclenchement avant le délai 
let maxing = false // Si le temps d'attente maximal est fixé maxWait, Utilisé principalement pour obtenir un effet d'étranglement 
let trailing = true // Le dernier déclencheur après le retard 
// Bypass `requestAnimationFrame` by explicitly setting `wait=0`.
const useRAF = (!wait && wait !== 0 && typeof root.requestAnimationFrame === 'function')
if (typeof func !== 'function') {
throw new TypeError('Expected a function')
}
// Conversion implicite
wait = +wait || 0
/** * isObject Déterminer si c'est un objet * function isObject(value) { * const type = typeof value * return value != null && (type == 'object' || type == 'function') * } */
if (isObject(options)) {
leading = !!options.leading
maxing = 'maxWait' in options
// maxWait Prends - le. maxWait Et wait Moyenne maximale, Pour obtenir un effet d'étranglement , Garantie requise maxWait La valeur réelle est supérieure à wait 
maxWait = maxing ? Math.max(+options.maxWait || 0, wait) : maxWait
trailing = 'trailing' in options ? !!options.trailing : trailing
}
/** ====== Interrupteur de minuterie ====== */
// Régler le minuteur
function startTimer(pendingFunc, wait) {}
// Annuler le minuteur
function cancelTimer(id) {}
// Calculer le temps d'attente restant 
function remainingWait(time) {}
// Rappel du minuteur 
function timerExpired() {}
/** ====== Exécution de la fonction ====== */
// Avant le délai 
function leadingEdge(time) {}
// Rappel après retard 
function trailingEdge(time) {}
// Mise en œuvre func Fonctions
function invokeFunc(time) {}
// Déterminer si l'exécution doit être effectuée à ce stade func Fonctions
function shouldInvoke(time) {}
/** ====== Rappel externe ====== */
// Annuler le délai 
function cancel() {}
// Appelez maintenant
function flush() {}
// Déterminer s'il est chronométré 
function pending() {}
// Fonction d'entrée
function debounced(...args) {}
debounced.cancel = cancel
debounced.flush = flush
debounced.pending = pending
return debounced
}
export default debounce
Copier le Code

Interrupteur de minuterie

 /** ====== Interrupteur de minuterie ====== */
// Régler le minuteur
function startTimer(pendingFunc, wait) {
if (useRAF) {
// Pas de réglage wait Ou paramètres wait Pour 0 Appel temporel window.requestAnimationFrame().
// Demande au navigateur de mettre à jour l'animation en appelant la fonction de rappel spécifiée avant le prochain redessinage
root.cancelAnimationFrame(timerId)
return root.requestAnimationFrame(pendingFunc)
}
return setTimeout(pendingFunc, wait)
}
// Annuler le minuteur
function cancelTimer(id) {
if (useRAF) {
return root.cancelAnimationFrame(id)
}
clearTimeout(id)
}
// Calculer le temps d'attente restant 
function remainingWait(time) {
// Heure actuelle et dernier appel debounce Intervalle
const timeSinceLastCall = time - lastCallTime
// Heure actuelle et dernière exécution func Intervalle
const timeSinceLastInvoke = time - lastInvokeTime
// Temps d'attente restant 
const timeWaiting = wait - timeSinceLastCall
// Si le temps d'attente maximal est fixé ( Réglage des gaz )
// Non: Temps d'attente restant 
// - Oui.: Temps d'attente restant Et Heure actuelle et dernière exécution func Intervalle Min in
return maxing
? Math.min(timeWaiting, maxWait - timeSinceLastInvoke)
: timeWaiting
}
// Rappel du minuteur 
function timerExpired() {
const time = Date.now()
// Devrait être mis en œuvre func Fonction, Effectuer un rappel après retard 
if (shouldInvoke(time)) {
return trailingEdge(time)
}
// Calculer le temps d'attente restant , Réinitialiser le minuteur 
timerId = startTimer(timerExpired, remainingWait(time))
}
Copier le Code

Exécution de la fonction

 /** ====== Exécution de la fonction ====== */
// Avant le délai 
function leadingEdge(time) {
// Définir la dernière exécution func Temps de la fonction 
lastInvokeTime = time
// Régler le minuteur
timerId = startTimer(timerExpired, wait)
// Si défini leading Exécuter immédiatement func Fonction une fois
return leading ? invokeFunc(time) : result
}
// Rappel après retard 
function trailingEdge(time) {
timerId = undefined
// trailing Continuer à déclencher une fois après le retard 
// lastArgs Marqué debounce Au moins une fois 
if (trailing && lastArgs) {
return invokeFunc(time)
}
// Réinitialiser les paramètres 
lastArgs = lastThis = undefined
return result
}
// Mise en œuvre func Fonctions
function invokeFunc(time) {
const args = lastArgs
const thisArg = lastThis
lastArgs = lastThis = undefined
lastInvokeTime = time
result = func.apply(thisArg, args)
return result
}
// Déterminer si l'exécution doit être effectuée à ce stade func Fonctions
function shouldInvoke(time) {
// Heure actuelle et dernier appel debounce Intervalle
const timeSinceLastCall = time - lastCallTime
// Heure actuelle et dernière exécution func Intervalle
const timeSinceLastInvoke = time - lastInvokeTime
// Premier appel
// Délai d'attente dépassé wait
// Le temps du système a changé 
// Temps d'attente maximal dépassé maxWait
return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
(timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait))
}
Copier le Code

Rappel externe

 /** ====== Rappel externe ====== */
// Annuler le délai 
function cancel() {
// Annuler le minuteur
if (timerId !== undefined) {
cancelTimer(timerId)
}
// Réinitialiser les paramètres 
lastInvokeTime = 0
lastArgs = lastCallTime = lastThis = timerId = undefined
}
// Appelez maintenant
function flush() {
return timerId === undefined ? result : trailingEdge(Date.now())
}
// Déterminer s'il est chronométré 
function pending() {
return timerId !== undefined
}
Copier le Code

étranglement:Lodash La réalisation de la fonction d'étranglement est simple , Appel direct à la fonction tampon , En définissant le paramètre maxWait Pour obtenir un effet d'étranglement .

function throttle(func, wait, options) {
let leading = true
let trailing = true
if (typeof func !== 'function') {
throw new TypeError('Expected a function')
}
if (isObject(options)) {
leading = 'leading' in options ? !!options.leading : leading
trailing = 'trailing' in options ? !!options.trailing : trailing
}
return debounce(func, wait, {
leading,
trailing,
'maxWait': wait
})
}
export default throttle
Copier le Code

Ce qui précède est vrai Lodash Brève analyse de la réalisation de l'anti - bavardage et de l'étranglement , Dans les scénarios d'affaires réels, la méthode anti - bavardage et d'étranglement est généralement utilisée directement. . Si vous avez besoin de fonctionnalités plus personnalisées, elles peuvent ne pas être implémentées ou ne pas prendre en charge la configuration , Vous pouvez envisager de vous mettre en œuvre vous - même avec une compréhension de son code source , Pour répondre aux besoins opérationnels réels .

Différence entre anti - bavardage et étranglement , Lequel utiliser selon le scénario d'affaires réel

Comparaison visuelle,Voir en ligne ( Note::Extrait de Stuart zhengmei - Anti - bavardage de la fonction et étranglement de la fonction )

L'anti - bavardage peut être utilisé pour des comportements proactifs imprévisibles de l'utilisateur , Par exemple, l'utilisateur entre le contenu dans le résultat de recherche dynamique du serveur . La vitesse à laquelle l'utilisateur tape, etc., est imprévisible , Irrégulier .

Les étranglements peuvent être utilisés pour un comportement actif non utilisateur ou prévisible de l'utilisateur , Envoyer une demande de point d'enfouissement si l'utilisateur glisse la fenêtre de l'article 、 La hauteur fixe coulissante est une logique connue , Régularité .

Résumé

Empruntez l'idée de l'anti - secousse et de l'étranglement , Pour contrôler le moment de l'exécution de la fonction , Économies de performance , Évitez les blocages de page, etc., qui peuvent causer une mauvaise expérience utilisateur . Les concepts de tamponnage et d'étranglement sont similaires et difficiles à distinguer , Le contenu ci - dessus a été introduit du point de vue de la compréhension de l'anti - secousse et de l'étranglement par l'auteur lui - même. .

Et les débutants peuvent être 《JavaScript Programmation avancée》 Ou d'autres articles techniques de l'auteur ont vu une compréhension et une introduction différentes ,Peut voir 《JavaScript Programmation avancée》Dans throttle En fait, oui. debounce、 La recherche dynamique devrait utiliser l'anti - tamponnage et la recherche en temps réel devrait utiliser différents points de vue et arguments tels que l'étranglement . J'espère que tout le monde pourra avoir sa propre compréhension de l'anti - secousse et de l'étranglement , Déterminer l'utilisation de l'anti - bavardage et de l'étranglement en fonction du scénario d'application réel et des détails de la demande. , Choisir une méthode plus raisonnable et plus appropriée .

Références

Stuart zhengmei - Anti - bavardage de la fonction et étranglement de la fonction

lodash Compréhension de la source d'étranglement anti - bavardage

Qu'est - ce que l'anti - bavardage et l'étranglement de la fonction ???

JavaScript Suivi du sujet underscore Apprendre à prévenir les tremblements

JavaScript Suivi du sujet underscore Apprendre l'étranglement

Lodash Comment l'anti - bavardage et l'étranglement sont - ils réalisés?

Lectures recommandées

Stock minimal de commerce électronique - SKU Et Réalisation de l'algorithme

Ce que vous devez savoir sur la gestion de projet

Comment 0 À 1 Construire un système de recherche de code global

Comment construire une plate - forme de déploiement adaptée à votre équipe

Travaux Open Source

  • Zhengcai Cloud Front End tabloïd

Open Source Address www.zoo.team/openweekly/ (Wechat Exchange Group est disponible sur la page d'accueil du site officiel du tabloïd)

Recruter des talents

Équipe de première ligne de Zhengcai Cloud(ZooTeam),Une équipe jeune, passionnée et créative,Affilié au Département de la recherche et du développement de produits Zhengcai Cloud,Base Dans le pittoresque Hangzhou.Équipe existante 50 Plus de partenaires frontaux,Âge moyen 27 Année,Proche 3 Je suis ingénieur en pile.,Troupe de jeunes orages.Les membres proviennent d'Ali、Netease“Vieux.”Soldat,Il y a aussi l'Université du Zhejiang.、University of Central Science and Technology、Nouveaux arrivants dans des écoles comme Hangzhou Electric Power.L'équipe est en dehors de l'amarrage quotidien des affaires,Toujours dans le système matériel、Plate - forme d'ingénierie、Construire une plateforme、Expérience de performance、Applications Cloud、Analyse et visualisation des données,Propulsé et mis en place une gamme de produits technologiques internes,Explorer continuellement les nouvelles limites du système technologique de première ligne.

Si tu veux changer, tu es toujours contrarié.,J'espère que ça va commencer.;Si vous voulez changer d'avis, il vous faut plus d'idées.,Mais il n'y a pas de solution.;Si vous voulez changer votre capacité à obtenir ce résultat,Je n'ai pas besoin de toi.;Si vous voulez changer ce que vous voulez faire, vous avez besoin d'une équipe pour le soutenir.,Mais il n'y a pas de place pour toi.;Si vous voulez changer le rythme établi,Ce sera“5 Heures de travail annuelles 3 Années d'expérience professionnelle”;Si tu veux changer, c'est une bonne idée.,Mais il y a toujours ce flou de papier de fenêtre… Si vous croyez au pouvoir de la foi,Croire que les gens ordinaires peuvent accomplir des choses extraordinaires,Je crois que je peux me rencontrer mieux..Si vous voulez participer au processus de démarrage de votre entreprise,Promouvoir personnellement une compréhension approfondie des affaires、Système technique parfait、La technologie crée de la valeur、Le processus de croissance de l'équipe de première ligne influente,Je pense qu'on devrait parler..À tout moment,J'attends que tu écrives quelque chose.,Envoyé à [email protected]

版权声明
本文为[Équipe de première ligne de Zhengcai Cloud]所创,转载请带上原文链接,感谢
https://qdmana.com/2021/10/20211013091846163a.html

  1. Nodejs + Serverless实现LaTeX公式渲染服务
  2. Analyse des questions d'entrevue: déstockage des tableaux et complexité temporelle
  3. Flux de données pour l'analyse des sources de vue
  4. Take group photos, sing songs and write blessings... Everyone on the Fuxing train celebrates the national day
  5. React核心 -- React-Hooks
  6. Mise en œuvre du Service de rendu de formule latex par nodejs + serverless
  7. React Core - React Hooks
  8. After autumn, wear less black, white and gray, and choose more gentle "light colors"
  9. Wu Qili sent blessings on the national day. She looked haggard and thin on her own. It was worrying
  10. Grand sens de la vue à la fois, la force dure est excellente, toute la série 2.0t, le film réel 2021 haver h9!
  11. With the blessing of Toyota power, GAC motor's new gs8 is open for pre-sale, starting from 188800 yuan
  12. Test drive Xingyue L: the price is less than 200000, but there are 400000 cards. Is it inevitable to sell more than 10000 a month?
  13. Entrevue de première ligne 3 + 1 tous les jours - jour 909
  14. Entrevue de première ligne 3 + 1 par jour - jour 910
  15. Xiao Zhan's 18 word blessing copy triggered a heated discussion, and fans expressed their attitude and wished the motherland together
  16. Engineering Knowledge Card 005: comment webpack injecte - t - il les ressources JS emballées dans html?
  17. ant design vue 设置表格选择框,全选按钮选不全
  18. 五分钟掌握用Vue脚手架搭建一个完整项目!
  19. 100 questions d'entrevue Python de base partie 2 (41 - 60)
  20. 五分鐘掌握用Vue脚手架搭建一個完整項目!
  21. ant design vue 設置錶格選擇框,全選按鈕選不全
  22. Cinq minutes pour construire un projet complet avec l'échafaudage vue!
  23. La vue de conception ant définit la zone de sélection de la table, le bouton sélectionner tout n'est pas sélectionné
  24. vuex中助手函数的几种使用技巧总结
  25. La nouvelle voiture roule à grande vitesse, le tableau de bord apparaît "tasse de café" prompt, directement au magasin 4S!
  26. Résumé de plusieurs techniques d'utilisation de la fonction Helper dans vuex
  27. Un disciple féminin est venu à guozijian: Zhuo Wenyuan a été complètement noirci, et le frère aîné de sang qi a été blessé par lui!
  28. JavaScript - - quatre façons de juger les types de données
  29. HTTPS|SSL笔记-SSL分手过程(Encrypted Alert)
  30. The film arrangement rate exceeds 40%, and the box office exceeds 390 million in less than two days! Why is Changjin lake?
  31. Nouvelle grande expérience de prise de vue en direct 2022 Geely Howe
  32. Apprenez à connaître CSS - Comment organiser votre code CSS
  33. Can the Zero run C11 with less than 200000 become the leader of medium-sized pure electric SUV?
  34. Https | SSL Notes - SSL break Process (encrypted Alert)
  35. HTTPS|SSL筆記-SSL分手過程(Encrypted Alert)
  36. Récemment, j'a i été interrogé par des fans sur les génériques Java, donc j'ai regardé en arrière et j'espère que l'entrevue de mon frère cadet se passera bien.
  37. Comment utiliser la nouvelle spécification es dans votre projet
  38. JavaScript - - orienté objet
  39. South Korean actress Liu Renna, wearing a white strapless skirt and walking on the red carpet, has a hot body and attracts eyes. She smiles so sweet
  40. Nginx (3): process model
  41. Projet Java: système de gestion du rendement des employés (Java + SSM + MySQL + Maven + HTML)
  42. CSS tips | one line of code to realize the integration of avatar and national flag
  43. Maotai and Paris Fashion Week joined hands to make Chinese elements appear on the show
  44. Wang Xiaoya showed up in a sleeveless skirt and reappeared her intellectual elegance. She was still full of temperament after leaving the nest CCTV
  45. Comment écrire un document de conception frontale
  46. Créer une api javascript haute performance avec Rust et l'exécuter dans webassembly
  47. Analyse de certains principes techniques clés du SDK de surveillance frontale
  48. Point de vue: la NFT de type portrait a formé un modèle d'entreprise. Quelles sont ses perspectives d'avenir et ses difficultés?
  49. Stars celebrate the motherland's birthday in patterns: Tang Yan Bixin, Liu Xiaoqing in military uniform, Zhao Liying and he Jiong send blessings
  50. L'amour entre Wing Mei et Luan Tree: de l'amour à première vue à l'amour éternel
  51. Disappeared car companies: tape measure is useless? Zhongtai is on the verge of death and has no way to return to heaven
  52. BUUCTF [极客大挑战 2019]Http
  53. element缓存到本地使用
  54. How can the volunteer army with less steel and more gas beat the American army with more steel and less gas? Changjin Lake gives you the answer
  55. CentOS installation source package nginx error
  56. Mise en cache des éléments pour utilisation locale
  57. Disappeared car companies: tape measure is useless? Zhongtai is on the verge of death and has no way to return to heaven
  58. He saifei est si naturel!58 ans est si beau, porter des vêtements de vieillesse pour accepter de vieillir!
  59. Finally pregnant! Seven years of pregnancy, collective blessing of the entertainment industry
  60. Wu Qili sent blessings on the national day. She looked haggard and thin on her own. It was worrying