Javascript承诺意外的执行流程

时间:2017-10-14 13:07:30

标签: javascript asynchronous promise

概述

我有一个带有跨度的html页面。内部文字说"初始状态"。一旦渲染了主体,脚本块就会加载,并且调用PersonService到UpdatePerson传入Person对象。 UpdatePerson方法休眠5秒钟以模仿需要一些时间的服务调用,然后返回带有"随机"的Promise。真或假的结果。然后,基于true或false的主代码块将在span内部文本中将消息设置为" Success"或"失败"。在承诺之后我将内部文本设置为"等待结果...."

跨度文本的预期顺序
 1)初始状态
 2)等待结果....
 3)(5秒钟后)......成功或失败

实际结果
1)初始状态
5秒钟后......
2)等待结果....
3)成功或失败

我认为一旦脚本执行到达消耗Promise的行,执行将立即继续到下一行,将内部文本设置为"等待结果......"然后当Promise状态从Pending(即5秒后)更改时,它将切换到执行解决或拒绝。承诺似乎是同步执行而不是异步执行。

我在这里缺少一些东西,无论是我的理解还是我如何模仿延迟调用另一个任务,即更新此人。有人可以解决我的困惑吗?

脚本通过body标签的onload属性启动,调用 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 个答案:

答案 0 :(得分:3)

这不是你如何模仿javascript的延迟。而是像这样使用window.setTimeout()

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

你正在做的是阻止,这在javascript中几乎总是坏的。