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

JavaScript Discussion :

Fonction ne marche qu'une seule fois


Sujet :

JavaScript

  1. #1
    Candidat au Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2018
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Septembre 2018
    Messages : 6
    Points : 4
    Points
    4
    Par défaut Fonction ne marche qu'une seule fois
    Bonjour !
    Mon site internet tourne depuis 12 ans mais cet été mon serveur a changé la version de php et mon code était désuet...
    Une partie du site ne fonctionnait plus et je pensais que c'était à cause des requêtes sql.
    Je reprend donc toutes les requêtes mysql en mysqli et en profite pour améliorer le site.
    Tout va bien mais là un simple appel à une fonction javascript me bloque.
    Voici un extrait épuré :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // début du code
    function Appeler()
        {
        // ici je log "debut appeler"
        // instructions
       TimeA=setTimeout(function() { CheckAppeler(1); }, 2000);// 2 secondes       
        }
     
    function CheckAppeler(comptetour)
        {
        // instructions
        TimeB=setTimeout(function() { Appeler(); }, 2000);// 2 secondes    
        }
    // fin du code
    Le résultat du log donne ceci :
    //début de l'extrait du log
    2018/09/01 17:18:19 debut appeler
    2018/09/01 17:18:23 debut appeler
    2018/09/01 17:18:27 debut appeler
    2018/09/01 17:18:31 debut appeler
    à l'infini....
    // fin de l'extrait du log
    Tout va bien, un appel a la fonction Appeler aux 4 secondes.
    J'obtiens ce résultat avec Firefox, Chrome et Edge en mode local .

    Par contre si j'exécute sur internet, j'obtiens:
    //début de l'extrait du log
    2018/09/01 17:18:19 debut appeler
    // fin de l'extrait du log
    Rien d'autre. On dirait que l'appel a une fonction ne peut se faire qu'une fois (:

    Je commence à me demander si ce n'était pas cela qui bloquait le fonctionnement du site...
    J'ai php version5.5.8 en mode local et 5.6.37 sur mon serveur net.
    j'obtiens le même résultat sur le net avec Firefox, chrome et edge.

    Merci de me guider, Jean

  2. #2
    Membre régulier
    Homme Profil pro
    developpeur web et android
    Inscrit en
    Octobre 2014
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Bénin

    Informations professionnelles :
    Activité : developpeur web et android
    Secteur : Services à domicile

    Informations forums :
    Inscription : Octobre 2014
    Messages : 64
    Points : 104
    Points
    104
    Par défaut
    y pas d'erreur dans le second résultat. dans "CheckAppeler" tu as appelé "Appeler" qui s’exécutera 2secondes après.
    Voici comment ça va fonctionner ton code :

    - l'appel de la function "CheckAppeler" va déclencher l'appel de la function"Appeler" deux seconde après (jusque la y aura pas de message log)
    - lorsque la function "Appeler" va commencer par exécuté, elle va s'exécuté une fois s'arrêté


    si tu veux que ça s'exécute a l'infinit chaque 2secondes utilise :
    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
     
    // début du code
    function Appeler()
        {
        // ici je log "debut appeler"
        // instructions
       TimeA=setInterval(function() { CheckAppeler(1); }, 2000);// 2 secondes       
        }
     
    function CheckAppeler(comptetour)
        {
        // instructions
        TimeB=setTimeout(function() { Appeler(); }, 2000);// 2 secondes    
        }
    // fin du code

  3. #3
    Candidat au Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2018
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Septembre 2018
    Messages : 6
    Points : 4
    Points
    4
    Par défaut problème toujours le même
    Merci,
    Je connais setInterval mais ce n'est pas la solution. Les lignes de codes dont je vous ai fais grâce contiennent des appels xhr , dont le retour prend parfois quelques millisecondes et parfois plusieurs secondes. C'est pourquoi CheckAppeler est appelé avec un compteur et il tourne sur lui meme , quand la réponses xhr arrive, il effectue des commandes javascript puis rappelle la fonction Appeler juste quand il a fini, en fait 2 secondes après avoir fini. Ca peut parfois prendre 5 ou 20 secondes donc set interval appellerai CheckAppeler trop vite ou trop souvent.

    J'ai quand même essayé setInterval et le résultat est exactement pareil: en local ça fonctionne mais pas sur le net.
    Pour moi c'est du mystère.

  4. #4
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 749
    Points
    4 749
    Par défaut
    Déjà, tu n'utilise pas la bonne syntaxe pour utiliser cette instruction =
    var identifiant = setTimeout( fonction[, delai, param1, param2, ...]);
    ce qui pour ton exemple de code s'écrit :
    Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function Appeler()
        {
        // ici je log "debut appeler"
        // instructions
       TimeA = setTimeout( CheckAppeler , 2000, 1);// 2 secondes       
        }
     
    function CheckAppeler(comptetour)
        {
        // instructions
        TimeB = setTimeout( Appeler, 2000);// 2 secondes    
        }

    Faut aussi savoir que les durée des délai (ici tes 2 secondes) sont rarement respectés par les interpréteurs JavaScript, et c'est d'ailleurs pour cette raison que la méthode delay en JQuery fait une vérification avec l'horloge interne et se relance quand le temps déroulé est plus court.

    Citation Envoyé par Jean Nadon Voir le message
    Les lignes de codes dont je vous ai fais grâce contiennent des appels xhr , dont le retour prend parfois quelques millisecondes et parfois plusieurs secondes.
    Il faut utiliser les promesses, ou jouer sur les callBack de tes appels Ajax (et en ESJ il y a maintenant les fetch, mais ça n'empeche pas qu'il faut quand même utiliser les promesses
    l'utilisation de setTimeOut ou SetInterval, sont à proscrire

    https://developer.mozilla.org/fr/doc..._les_promesses

    https://developer.mozilla.org/fr/docs/Web/API/Fetch_API

  5. #5
    Candidat au Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2018
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Septembre 2018
    Messages : 6
    Points : 4
    Points
    4
    Par défaut Plus de détail sur le pourquoi de mes appels à Appeler()
    Merci pour votre aide,
    J'utilise normalement la syntaxe de psychédélic mais en creusant mon problème , j'ai lu que l'autre façon était LA bonne ...
    De toute façon lors de mes tests les 2 façons de faire donnent la même réponse.
    Donc pourquoi ces appels en boucle? Depuis 12 ans , mon site offre un jeu de carte . 4 clients affichent la table de jeu avec leur 13 cartes.
    Chaque deux secondes, un appel xhr vérifie la base de donnée, si aucun changement, on re-appel dans 2 secondes. S'il y a un changement (carte de jouée par un autre joueur par exemple) la réponse du xhr met a jour le déplacement des cartes , qui peut jouer etc. Quand la table est prête , on ré-appel dans 2 secondes.
    Avec 4 joueurs aux 2 secondes , une partie qui dure 20 minutes et 10835 rencontres de plusieurs parties ça fait 100 millions de fois que ça fonctionne.
    Je veux bien améliorer mon code pour suivre les nouvelles technologies mais quand ça marche en mode local et que les mêmes scripts ne fonctionne pas sur internet je ne sais pas quoi faire.
    PS J'ai écrit à mon hébergeur web...

  6. #6
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Tu dis que ces fonctions font appel à Ajax.

    Il est fort possible que ce soit un script PHP (appelé par Ajax) qui foire.


    Passe en version 5.6 en local.
    Tu verras bien.

  7. #7
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 749
    Points
    4 749
    Par défaut
    Citation Envoyé par jreaux62 Voir le message
    Passe en version 5.6 en local.
    +1

    c'est le B.A.BA => avoir la même configuration en test et en Exploitation.

    Qu'est_ce que tu utilises pour tester en Local, tu as un serveur perso ?
    j'ai un gros doute aussi sur ta façon de coder ta réponse AJAX coté PHP
    des trucs mal codés qui fonctionne pendant des années et qui tout à coup ne marchent plus lors d'une mise à jour, c'est toute l'histoire de l'informatique,
    et s'imaginer que parce que ça marchait avant alors ça devrait marcher maintenant c'est tout sauf un raisonnement cartésien

    Sinon ce genre de truc ne se code pas du tout de la façon que tu as choisi, à minima il faut utiliser un SetInterval que tu stops (clearInterval ) et relances après chaque réponse de changement, mais ce serait mieux d'utiliser l'API EventSource (hélas pas implémenté sur IE).

    https://caniuse.com/#search=EventSource
    https://www.html5rocks.com/en/tutori...source/basics/

    https://www.developpez.net/forums/bl...est-lutiliser/

  8. #8
    Candidat au Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2018
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Septembre 2018
    Messages : 6
    Points : 4
    Points
    4
    Par défaut Merci pour votre aide, je retourne tester...
    Merci psychadélic et Jreaux62, vous avez raison quand c'est le B.A.BA => avoir la même configuration en test et en Exploitation.
    Je fonctionne en local avec EasyPHP DevServer 14.1 VC11 avec php5.5.8 J'ai testé avec la version php 5.3.29 sur mon serveur internet que j'avais il y a 2 mois et le problème est le même. J'hésite donc à modifier mon installation personnelle...La dernière fois ça a été l'enfer pour refaire fonctionner.
    J'ai refais des tests en épurant au maximum le code et en ne gardant que l'appel aux fonctions. J'ai aussi loggué différemment.
    J'ai pus voir alors que la boucle tourne bien. Il n'y a pas de problème avec l'appel aux fonctions. La question du forum ici est donc résolue.
    Par contre mon problème reste entier: je ne sais toujours pas pourquoi il y a des résultats différents.
    J'ai bien hâte d'avoir la réponse de mon hébergeur web.
    Bonne programmation à tous!

  9. #9
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 749
    Points
    4 749
    Par défaut
    Citation Envoyé par Jean Nadon Voir le message
    Je fonctionne en local avec EasyPHP DevServer 14.1 VC11 avec php5.5.8 J'ai testé avec la version php 5.3.29 sur mon serveur internet que j'avais il y a 2 mois et le problème est le même. J'hésite donc à modifier mon installation personnelle...La dernière fois ça a été l'enfer pour refaire fonctionner.
    Faut arrêter avec les EasyPHP et autres WampServer , XAMPP. utilise Docker, comme tu peux choisir à la carte tes configs selon tes besoins et activer / désactiver seulement ceslles dont tu a besoin.

    Sinon encore une fois :
    1 je doute que ton PHP de réponse AJAX soit correct, dans 99% des cas les codeurs ne mettent pas les entêtes http, et autres..
    2 l'utilisation des setTimeout n'est pas faite pour ce type d'utilisation et tu aura toujours des problemes pour ce genre de besoin, si tu ne veux pas utiliser de Server-Sent Events il faut utiliser les promesses.

  10. #10
    Invité
    Invité(e)
    Par défaut
    bj

    1) Pourquoi les callbacks sont elles à proscrire?
    2) l'appel de Jean est parfaitement valide n'en déplaise à l'esthétisme..
    ----
    concernant l'erreur, possibilités sont:
    tu as avec la nouvelle version de php que je présume est utilisée avec un certain framework??
    - des scripts qui sont inclus dans ta page mais pas dans le meme ordre
    - des scripts qui sont juste bugguées et plantent ton execution (donc c'est ptet juste un hasard que tu voies le premier log, c'est juste que ca rame..)
    - ton script rentre en conflit avec les scripts (qui sont générés dynamiquement par ton framework)

    - ton appel ajax est KO parce que ton serveur attend un autre type de demande: idem le serveur te repond pas un truc valide et du coup tu continues pas tes appels réseaux.

    Dans tous les cas, step 1
    tu "inspectes" la console de chrome/ff pour voir si c'est un appel réseau qu'est piné ou si c'est une erreur js

    edit: pinky finger me dit que t'as une ou deux fonctions php qui sont pétées lors de ton call ajax et donc ton serveur retourne KO (puis apres tu chaines plus tes requetes ajax).
    Verifies/conforte by step 1, mais pbmlt t'as le droit de te farcir les changements cassant de php (comment dit on en francais ) entre les deux versions...

  11. #11
    Candidat au Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2018
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Septembre 2018
    Messages : 6
    Points : 4
    Points
    4
    Par défaut Résolu
    En modifiant le contenu de la bd et en modifiant mes requêtes, je me suis rendu compte que le résultat d'un script était toujours le même. C'est la raison pour laquelle il ne détectait pas les changements dans la bd et semblait bloqué.
    Je me suis souvenu qu'il fallait ajouter un paramètre bidon aux requêtes pour éviter que le système pense que c'est la même requête.
    Ce paramètre bidon doit changer constamment à chaque appel de requête.

    AVANT:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(!req0.getFileGet("LireZM.php","NoTable="+JSNoTable+"&NoJoueur="+JSNoJoueur))
    APRÈS:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    var date_jour=new Date();
    var sec=date_jour.getSeconds();	
    if(!req0.getFileGet("LireZM.php","NoTable="+JSNoTable+"&NoJoueur="+JSNoJoueur+"&nimporte="+sec))
    J'ignore pourquoi il y a cette différence dans divers environnement.

    Maintenant tout va bien, merci beaucoup pour votre temps à me répondre.

  12. #12
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 749
    Points
    4 749
    Par défaut
    Citation Envoyé par Jean Nadon Voir le message
    En modifiant le contenu de la bd et en modifiant mes requêtes, je me suis rendu compte que le résultat d'un script était toujours le même. C'est la raison pour laquelle il ne détectait pas les changements dans la bd et semblait bloqué.
    Je me suis souvenu qu'il fallait ajouter un paramètre bidon aux requêtes pour éviter que le système pense que c'est la même requête.
    Ce paramètre bidon doit changer constamment à chaque appel de requête.
    eh ben voila...
    c'est pas une question de version de php, mais de version de serveur. donc normal que ça ne fonctionne pas pareil localement et avec ton hébergeur.

    Raison de plus pour utiliser Docker, car on peut aussi choisir la version du serveur, dur serveur SQL, de PHP, etc...

    Donc ton histoire est une affaire de cache. toute requête et sa réponse sont enregistrés dans un cache, quand une nouvelle requête arrive, si elle est identique dans sa demande avec l'une de celle conservée dans le cache, alors le serveur renvoie la même réponse, sans même, ici, aller interroger le serveur SQL, ou alors le serveur SQL à lui même ce genre de mécanisme.

    Donc ton idée d'ajouter un éléments "bidon" mais surtout changeant, squize ce système de cache et l'oblige à vraiment interroger ta base de donnée.
    Sauf que dans ton système , le serveur continue à engranger dans son cache tes requêtes répétées, et remplie donc inutilement sont cache ce qui freine un peu ton système.
    Si tu à 12 pékins branché sur ton jeu ça représente des cacahuètes, mais pas si tu en à 1 million.

    Donc dans ce cas la, il vaut mieux prévenir le serveur que ta requête en question ne doit pas être mise dans un cache, ce qui justement se code dans le header de la réponse PHP.

    Citation Envoyé par psychadelic Voir le message
    1 je doute que ton PHP de réponse AJAX soit correct, dans 99% des cas les codeurs ne mettent pas les entêtes http,
    tu ferai mieux demettre dans ton code PHP ce header :
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
    header("Cache-Control: post-check=0, pre-check=0", false);
    header("Pragma: no-cache");
    header("Expires: 0"); // Proxies.

    ça t'évitera d'avoir à penser que les systèmes ont leur lubies qu'on doit contourner des astuces de bricoleur.

  13. #13
    Candidat au Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2018
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Septembre 2018
    Messages : 6
    Points : 4
    Points
    4
    Par défaut ca va bien
    Bonjour, désolé pour le délai j'étais en vacances...
    Psychedelic a mis dans le mille.
    J'ai ajouté les headers de no-cache etc et tout va bien, probablement même mieux qu'avant.
    Puisqu'un joueur envoie dans sa requête sa carte(un numéro de 1 à 52) et une position de joueur(1 à 4 selon qu'il est le premier à jouer ou le 4 ieme)
    Il devait arriver que dans une seconde partie un joueur joue la même carte tandis qu'il est au même rang à jouer, comme la requête était la même,
    la réponse était en cache alors un bug survenait dans le déroulement du jeu. Merci!

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

Discussions similaires

  1. [XL-2010] Fonction qui ne marche qu'une seule fois
    Par haydens dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 18/07/2012, 10h04
  2. DataGrid drag & drop qui ne marche qu'une seule fois
    Par ludogoal dans le forum Windows Presentation Foundation
    Réponses: 3
    Dernier message: 19/06/2009, 09h24
  3. breakpoints, step into ne marche qu'une seule fois..
    Par Brzhk dans le forum Eclipse C & C++
    Réponses: 0
    Dernier message: 11/06/2009, 16h15
  4. [XL-2003] fonction mscomm1.input utilisable une seule fois?
    Par Elfstat dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 12/04/2009, 13h02
  5. KeyDown sur form ne marche qu'une seule fois
    Par Mariquiqui dans le forum Windows Forms
    Réponses: 1
    Dernier message: 22/01/2009, 19h47

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