2016-12-01 4 views
0

J'ai une page avec la configuration ci-dessous. J'ai des problèmes de synchronisation car j'appelle une fonction, définie plus tard dans le corps, à partir d'un rappel dans l'en-tête. Je dois m'assurer que doSomething(stuff) est seulement exécuté une fois myScript.js et la balise de script finale sont évaluées.Vérification de l'exécution des fonctions Javascript et des rappels dans l'ordre correct

Certaines choses que j'ai essayé:

  • utilisant window.onload - il n'y a aucune garantie que le rappel sera exécutée avant que la fenêtre se termine le chargement.
  • en utilisant setTimeout pour vous assurer que doSomething est défini, et continuez à l'essayer jusqu'à ce qu'il soit défini. Cela fonctionne, mais je m'inquiète que sur les connexions lentes ou une page occupée, cela prendra du temps et bloquera.
  • définissant doSomething dans l'en-tête aussi bien et l'utiliser uniquement pour assigner la variable d'accéder à plus tard dans le corps (j'ai posté le code ci-dessous pour afficher cette option)

Quelle configuration dois-je utiliser pour faire correctement assurer que tout le code sur la page est exécuté dans le bon ordre, et aussi rapidement que possible?


<head> 
<script type="text/javascript"> 
    var myQueue = []; 
    myQueue.push(function(){ 
     getSomeStuff({ 
      timeout: 4000, 
      gotStuffCallback: function(stuff){ 
       doSomething(stuff); 
      } 
     }) 
    } 

</script> 
</head> 
<body> 
<!-- a script that takes an undetermined amount of time to execute --> 
<script src="myScript.js"></script> 

<script type="text/javascript"> 
    var doSomething = function(stuff){ 
     // uses code from the external js file myScript.js 
     useMyScript(stuff); 
    }; 
</script> 
</body> 

Code pour la troisième option:

<head> 
<script type="text/javascript"> 
    var myQueue = []; 

    var headerStuff; 
    var doSomething = function(stuff){ 
     headerStuff = stuff; 
    } 

    myQueue.push(function(){ 
     getSomeStuff({ 
      timeout: 4000, 
      gotStuffCallback: function(stuff){ 
       doSomething(stuff); 
      } 
     }) 
    } 

</script> 
</head> 
<body> 
<!-- a script that takes an undetermined amount of time to execute --> 
<script src="myScript.js"></script> 

<script type="text/javascript"> 
    var doSomething = function(stuff){ 
     var stuff = headerStuff || stuff; 
     // uses code from the external js file myScript.js 
     useMyScript(stuff); 
    }; 
</script> 
</body> 

Edit: ajouté manquant var devant myQueue.

+0

tag myScript est obligatoire d'être sur le corps du document? – Jorge

+0

Pas nécessairement, mais comme cela pourrait prendre un certain temps à s'exécuter, j'aimerais le mettre le plus tard possible sur la page. – ekrah

+0

Où 'myQueue' a-t-il démarré? – Bergi

Répondre

0

Si vous pouvez utiliser des promesses et il n'y a aucune raison que vous ne pouvez pas (vous pouvez toujours polyfiler avec bluebird).

Vous pouvez créer une promesse en tête de votre fichier html, en continuant comme callbacks et le résoudre dans le dernier bloc javascript.

va ici:

<head> 
 
    <script> 
 
    var trigger; 
 
    alert('start') 
 
    new Promise(function(resolve) { 
 
     trigger = resolve; 
 
     }) 
 
     .then(
 
     function() { 
 
      // call your callback here 
 
      alert('callback'); 
 
     }); 
 
    </script> 
 
</head> 
 

 
<body> 
 
    <!-- here goes your long runing script --> 
 

 
    <script> 
 
    alert('finish'); 
 
    trigger(); 
 
    </script> 
 
</body>