Maison  >  Article  >  interface Web  >  Résolution réussie de l'événement personnalisé et résolution du bug des demandes répétées

Résolution réussie de l'événement personnalisé et résolution du bug des demandes répétées

巴扎黑
巴扎黑original
2017-07-22 15:32:381478parcourir

De nos jours, le développement de composants est toujours très populaire, après tout, ses avantages sont assez importants. Récemment, lors du développement d'un composant, j'ai rencontré un BUG très intéressant. . .

Contexte du BUG

Récemment, je développais un composant, et il a finalement été terminé et testé. Ensuite, le test m'a mentionné ce bug, orz...

Comme c'est un composant, le plus gros avantage est qu'il peut être réutilisé et utilisé n'importe où. Cependant, Lorsqu'une page utilise plusieurs composants et que seul le dernier prend effet, ce composant n'a aucun sens. . .

Recherche de cause de BUG

L'interface de la source de données initiale de ce composant est corrigée, c'est-à-dire que tous les composants de la page émettront le même message lorsque initialisation. La requête ici est sous forme de jsonp, donc la fonction de rappel est une fonction liée à la fenêtre, mais il n'y a qu'une seule fenêtre dans la page, donc lorsque le rappel est traité, les données correspondantes dans le composant à traiter. pointe uniquement vers le dernier composant. En conséquence, plusieurs composants identiques sont placés sur la même page et seul le dernier composant peut être restitué avec succès après avoir obtenu les données.

Idées de solutions BUG

Le plus important est de stocker le rappel de chaque requête, afin de garantir que le traitement des données des composants dans le rappel ne se limite pas montrez le dernier. Deuxièmement, puisqu'il s'agit de la même requête, nous ne souhaitons bien sûr pas qu'elle soit émise plus de deux fois, c'est-à-dire que chaque requête émise par une page est unique.

Solution BUG

J'ai pensé à publier des événements personnalisés en mode abonné. Vous pouvez écrire un tel module pour déterminer s'il y a le même événement avant l'émission de chaque requête. Le module a été émis. Sinon, le rappel du cache émettra la demande. Si la même demande a été émise, vérifiez si la demande émise a été exécutée. Sinon, continuez à mettre en cache le rappel et attendez si la demande a été émise. été émis et complété. Ensuite, gérez directement le rappel. Après le premier retour de la requête, une diffusion est émise et tous les rappels précédemment mis en cache sont exécutés.

Détails de l'événement personnalisé

Définissez un module avec n objets d'événement nommés d'après les fonctions de rappel. Chaque objet a sa propre définition lorsqu'il est initialisé, le tableau de rappel correspondant. , et les données renvoyées par la requête. A chaque appel de ce module, vérifiez d'abord si le cbName correspondant est initialisé, puis vérifiez son état. Effectuez les opérations correspondantes en fonction de l'état et modifiez la valeur de l'état. Il existe trois valeurs d'état, à savoir init, chargement et chargé. C'est-à-dire initialiser, demander et demander l'achèvement. Le rappel correspondant ne peut être exécuté que lorsque la requête est terminée. Les détails sont les suivants :

define('wq.getData', function (require, exports, module) {
    var ls = require('loadJs');
    
    var cache = {};
    cache.init = function(cb,cbName,url){
        if(!cache[cbName]){
            cache[cbName] = {};
            cache[cbName].state = 'init';
            cache[cbName].cbs = [];
            cache[cbName].data = [];
        }
        cache.on(cb,cbName,url);
    }
    cache.on = function(cb,cbName,url){
        if(cache[cbName].state == 'loaded'){
            cb(cache[cbName].data)
        }else if(cache[cbName].state == 'loading'){
            cache[cbName].cbs.push(cb)
        }else if(cache[cbName].state == 'init'){
            cache[cbName].cbs.push(cb);
            cache[cbName].state = 'loading';
            cache.fetch(cb,cbName,url);
        }
    }
    cache.broadcast = function(cbName){
        cache[cbName].cbs.forEach(function(cb){
            cb(cache[cbName].data)
        });
    }
    cache.checkLoaded = function(cbName){
        if(cache[cbName].data[0]){
            cache[cbName].state = 'loaded';
            cache.broadcast(cbName);
        }
    }
    cache.fetch = function(cb,cbName,url){
        ls.loadScript({
            url: url,
            charset: 'utf-8',
            handleError:function(func, args, context,errorObj){
                console.log(_errlogText + context);
                cache[cbName].data[0] = {};
                cache.checkLoaded(cbName);
            }
        });
        if(window.cbName) return;
        window[cbName] = function(json){
            cache[cbName].data[0] = json;
            cache.checkLoaded(cbName);
        }
    }

    exports.getData = function(cb,cbName,url){
        cache.init(cb,cbName,url);
    }  

})

Résolvez parfaitement le problème, chaque rappel ne sera pas manqué ou écrasé...

Agrandir idées

Ce module peut être utilisé de manière universelle pour traiter la même demande au sein d'une page. Il peut également être étendu pour gérer les situations qui nécessitent que plus de deux requêtes soient complétées avant d'exécuter un certain rappel. Similaire au cas de Promose. A ce stade, on peut stipuler que chaque data[0] contient une donnée fixe correspondant à l'interface, data[2] correspond à une autre, et ainsi de suite. Cependant, cela nécessite un parcours jusqu'à ce que chaque élément soit vrai avant d'exécuter le rappel. De plus, la relation correspondante est facile à confondre, et il est préférable d'utiliser Promise pour la gérer si vous l'étendez davantage. . .

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