2017-10-14 13 views
0

Vue d'ensembleJavascript promet exécution inattendue flux

J'ai une page html avec une portée. Le texte intérieur dit "Etat initial". Le bloc de script se charge une fois que le corps a été rendu et il y a un appel à un personService à UpdatePerson passant dans un objet Person. La méthode UpdatePerson dort pendant 5 secondes pour imiter un appel de service qui prend un certain temps, puis renvoie une promesse avec un résultat "aléatoire" vrai ou faux. Le bloc de code principal basé alors sur vrai ou faux placera le message dans le texte intérieur de span à «succès» ou «a échoué». Après la promesse que je mets le texte intérieur pour "En attente .... résultat"

ordre attendu du texte dans Span
1) état initial
2) Résultats .... En attente de
3) (5 secondes plus tard) .... Le succès ou Failed

résultats réels
1) initial de l'Etat
5 secondes plus tard ...
2) résultats ....en attente de 3) Succès ou Échec

Je pensais qu'une fois que l'exécution du script atteignait la ligne qui consomme la promesse que l'exécution continuerait immédiatement à la ligne suivante qui définit le texte interne à "Attente de résultat ..." et puis quand l'état Promise est passé de Pending (c'est-à-dire 5 secondes plus tard) il passe alors à l'exécution de resolve ou reject. La promesse semblait s'exécuter de manière synchrone plutôt qu'asynchrone.

Il me manque quelque chose ici, soit dans ma compréhension, soit dans la façon dont j'ai fait pour imiter un retard dans un appel à une autre tâche, c'est-à-dire mettre à jour la personne. Quelqu'un peut-il éclaircir ma confusion?

script commence par l'attribut onload de la balise body appelant StartExample()

function Sleep(milliseconds) { 
     var start = new Date().getTime(); 
     for (var i = 0; i < 1e7; i++) { 
     if ((new Date().getTime() - start) > milliseconds){ 
      break; 
     } 
     } 
    } 

    function Person(name, age, gender) 
    { 
    this.name = name; 
    this.age = age; 
    this.gender = gender; 
    } 

    personService = {} 

    personService.UpdatePerson = function(person){ 
    Sleep(5000); 
    return Promise.resolve((Math.random() >= 0.5)); 
    }; 

    function StartExample(){ 

     var resolve = function(){ 
       // get resultSpan from DOM, write "Success" message 
     } 

     var reject = function(){ 
      // get resultSpan from DOM, write "Failed" message 
     } 

     var p = new Person("tom", 15, "m");    

     personService.UpdatePerson(p) 
     .then(function(result){ 
      if(result){resolve();} 
      else{reject();} 
     }) 
     .catch(error => { alert(error);}) 

     var resultSpan = document.getElementById("resultSpan"); 
     resultSpan.innerText = "Awaiting result...";  
    } 
</script> 

<span id="resultSpan" style="background-color: blue;">Initial State</span> 
+1

Vous ne devriez pas dormir comme ça en javascript ... Ce que vous avez écrit bloquera le thread principal car il est synchrone, donc il attendra que la fonction de veille soit terminée. – August

+1

'Sleep (5000);' Empêche le navigateur de faire autre chose pendant 5 secondes – Andreas

Répondre

3

Ce n'est pas comment vous imitez un retard dans javascript. Au lieu d'utiliser window.setTimeout() comme ceci:

personService.UpdatePerson = function(person){ 
     return new Promise(function(resolve) { 
      window.setTimeout(function() { 
       resolve(Math.random() >= 0.5), 
      5000); 
     }); 
    }; 

Qu'est-ce que vous faites bloque, ce qui est à peu près toujours mauvais en javascript.

+0

Merci, je savais que je faisais quelque chose daft quelque part – user1054637