IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

jQuery Discussion :

jquery.deferred, fancytree, et IIFE


Sujet :

jQuery

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    1 616
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 616
    Par défaut jquery.deferred, fancytree, et IIFE
    Bonjour

    Une question sur un phénomène qui m'échappe un peu, que je présume lié à l'asynchronisme mais sans vraiment arriver à me l'expliquer.
    Enfin en tout cas je cherche un éclairage.

    Donc voici mon bout de code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    function expandResultNodes(responseText)  { 
        var result_keys=[];
        $.each(responseText, function( index, keypath) {
            result_keys.push(keypath.split("/").pop());
        });
        var FTPtree = $("#Tree_sasFTP").fancytree("getTree") ;
     
        // Use deferred promise:
     
        FTPtree.loadKeyPath(responseText).done(function(){
            defferedFilterNodes(FTPtree);
        });
        // FTPtree.loadKeyPath(responseText).done(
            // defferedFilterNodes(FTPtree)
        // );
     
        function defferedFilterNodes (tree){
            tree.filterNodes(function(node) {
                console.log("filtering " + node.key);
                return result_keys.some(function(element) {
                    // checks whether a result_keys element equals node key
                    return element == node.key;
                });
            });
        }       
    }
    j'envoie en AJAX une requête de recherche de mots-clés sur mon serveur, la recherche s'effectue sur le serveur sur une partie du file system qui correspond à une zone de dépose FTP, le serveur renvoie une réponse en JSON qui est constituée d'un tableau de chemins de clefs. Exemple de réponse mis en forme par firefox :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
     
    0	"/_f83b45b7c4d40be3b25b7abfcb7226c4/_eb8cf44ea2366ae3cf1af572d5a818e0/_393d735d160b9d21ddde00b739991e59"
    1	"/_f83b45b7c4d40be3b25b7abfcb7226c4/_eb8cf44ea2366ae3cf1af572d5a818e0/_32a9a6fc7652124f1882f52e2316ee0e"
    2	"/_f83b45b7c4d40be3b25b7abfcb7226c4/_eb8cf44ea2366ae3cf1af572d5a818e0/_32a9a6fc7652124f1882f52e2316ee0e/_19a2fd29b73244e41f9eaa4ec6dc5e79/_fb58a0b2d0e222117b83e361be8643e4"
    3	"/_f83b45b7c4d40be3b25b7abfcb7226c4/_eb8cf44ea2366ae3cf1af572d5a818e0/_32a9a6fc7652124f1882f52e2316ee0e/_19a2fd29b73244e41f9eaa4ec6dc5e79/_32a1178799b476d197251c2d1e617903"
    [...]
    24	"/_f83b45b7c4d40be3b25b7abfcb7226c4/_eb8cf44ea2366ae3cf1af572d5a818e0/_f45e1e6c72e2e8a80889794671538c6e/_11fe4e4e36adeacf04d8efbffcf4259a/_16b6520368113327455a2574562a902f"
    25	"/_f83b45b7c4d40be3b25b7abfcb7226c4/_eb8cf44ea2366ae3cf1af572d5a818e0/_123fcfdc7ff35b145093d9ff49ada47b"
    Ces clefs sont des éléments identifiants pour les nœuds d'une arborescence représentée par Fancytree : https://github.com/mar10/fancytree

    A la base, avant de recevoir cette réponse Fancytree ne représente que le premier niveau de répertoires, donc la racine et 8 répertoires sous-jacents.

    le code une fois la réponse JSON reçue, charge de manière "lazy" (lazy loading==requêtes AJAX pour chaque nouveau noeud ou branches à visualiser qui n'est pas déjà présent)
    C'est ce que fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FTPtree.loadKeyPath(responseText)
    la doc de cette fonction loadKeyPath ici : http://wwwendt.de/tech/fancytree/doc...ml#loadKeyPath

    puis une fois les branches adéquates chargées, je vais mettre en évidence les résultats de la requête. En fait ces résultats sont les clefs terminales de chaque ligne du tableau des chemins.
    d'où le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    var result_keys=[];
        $.each(responseText, function( index, keypath) {
            result_keys.push(keypath.split("/").pop());
        });
    qui ne garde que le dernier élément de chaque ligne pour en constituer un nouveau tableau correspondant aux résultats effectifs de la requête.

    et donc à la fin de loadKeyPath, je filtre les résultats avec cette fonctionnalité, extension de fancytree :
    https://github.com/mar10/fancytree/wiki/ExtFilter
    en comparant les éléments du tableau des résultats avec les clefs précédemment chargées, ce que fait la fonction defferedFilterNodes

    le truc c'est que si j'appelle cette fonction directement dans le .done(), seuls les éléments affichés avant l'exécution de loadKeyPath sont filtrés, donc le premier niveau d'arborescence, alors que tous les éléments sont bien chargés
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        FTPtree.loadKeyPath(responseText).done(
            defferedFilterNodes(FTPtree)
        );
    Si j'appelle cette fonction dans le cadre d'une IIFE, ça marche nickel et tous les résultats, toutes les branches == tous les éléments transmis sont bien filtrés et mis en évidence
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        FTPtree.loadKeyPath(responseText).done(function(){
            defferedFilterNodes(FTPtree);
        });
    J'ai bien l'intuition de ce qui se passe, mais je ne sais pas me l'expliquer avec des notions réellement formelles liées à Javascript.

    Quelqu'un saurait il m'expliquer ce phénomène ? aussi bête soit-il ou non ?

  2. #2
    Membre extrêmement actif Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 532
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 532
    Par défaut
    Oui, c'est bien une gestion Asynchrone, et il y a donc une gestion de promesses, ici codées au travers des méthodes done ou "IIFE" qui doit se trouver quelque part dans leur doc..

  3. #3
    Membre Expert
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    1 616
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 616
    Par défaut
    En fait ce que je voulais dire, c'est pourquoi dans un cas, sans l'IIFE, le programme semble voir le DOM avant qu'il n'ai été mis à jour par l'appel à loadKeyPath, et pourquoi si cette même fonction est appelée dans le cadre de l'IIFE, elle voit le DOM tel qu'il a été mis à jour ?

    Je vais poser cette même question sur le forum Fancytree, mais si c'est un mécanisme qui n'est pas lié spécifiquement à Fancytree mais à la gestion des promises et plus généralement au JavaScript, je veux bien que quelqu'un éclaire ma lanterne.

  4. #4
    Membre extrêmement actif Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 532
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 532
    Par défaut
    Quand l'interpréteur JS se retrouve à traiter une fonction asynchrone, il lance un process en parallèle pour s'en occuper, et il continue avec les instruction suivantes, sans ce soucier du résultat ni des changements sur les variables.

    grosso modo
    Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    var XYZ = 5;
    fonctionAsync_raz_XYZ();
    console.log(XYZ);  // renvoie 12, XYZ reste inchangée
    // ....
     
    // 10 minutes plus tard quand la fonctionAsync_raz_XYZ() est achevée : 
    console.log(XYZ);  // renvoie 0, XYZ à été remis à zéro par la fonctionAsync_raz_XYZ

    en javascript on parle de fonction asynchrones,
    et jQuery part de l'idée que ce sont des fonctions qui finiront par s'exécuter de maniéré différées, d’où leur nom : defered

  5. #5
    Membre Expert
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    1 616
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 616
    Par défaut
    oui ça pas de souci

    sauf que là tu m’expliques l'asynchronisme, pas ce que je cherche à comprendre. Ni pourquoi l'IIFE casse (ou résoud) ce mécanisme décrit plus haut.

    En gros avec les outils de dev et la console javascript, je vois bien que defferedFilterNodes est appelé à la fin de loadKeyPath, après son exécution complète, et non pas de manière asynchrone, parallèle mais bien comme un callback

    Dans un cas defferedFilterNodes voit le Tree et donc le DOM comme il est avant l'exécution de loadKeyPath, et avec l'IIFE comme il est après. Dans les 2 cas, les fonctions sotn appelées en callback du .done de loadKeyPath

    C'est ça que je ne comprends pas, et c'est plutôt à l'opposé de ce que tu me décris.

    M'enfin je ne comprends pas alors peut-être pas plus ton explication, sauf que je ne vois pas comment tu l'appliques à ce cas concret.

  6. #6
    Membre extrêmement actif Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 532
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 532
    Par défaut
    Si tu dois exploiter le résultat d’une fonction asynchrone, il faut utiliser un mécanisme qui attende la fin de l’exécution de cette fonction async.

    En Javascript ce mécanisme fonctionne en 2 parties*:
    premier partie sur la fonction asynchrone elle même pour qu’elle puisse en voyer un signal comme quoi elle s’est bien terminée terminée ou non, et dans ce cas l’interpréteur active un abandon*;

    en js çà s*‘écrit ; function MuFctAsync() { return new Promise(function(resolve, reject){ … })*; }


    la deuxieme partie c’est la fonction qui appelle la fonction async et qui se charge de traiter la suite et en fonction de statut de retour de cette fct async.

    Comme en JS on est dans un langage objet, il peut y avoir une douzaine de mêmes fonctions Async en même temps et et convient de bien lier ensemble les fonctions qui doivent encadrer les process asynchrone et les fonctions asynchrones elles mêmes.

    Si tu faits les trucs dans le désordre, en liant des parties qui ne se correspondent pas ça ne pourra jamais marcher.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 6
    Dernier message: 14/01/2005, 10h36
  2. documentation sur deferable
    Par champion dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 13/09/2004, 22h18
  3. [SQL] INITIALLY DEFERRED DEFERRABLE
    Par Boosters dans le forum Administration
    Réponses: 8
    Dernier message: 05/03/2004, 19h05
  4. Fonction IIF
    Par ParisMath dans le forum SQL
    Réponses: 2
    Dernier message: 16/01/2004, 22h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo