使用Promise同步函数调用

时间:2018-01-15 13:47:05

标签: javascript jquery promise synchronization

我尝试同步功能调用但不想使用回调。我对这些东西还很陌生,所以赞赏一点点解释

var h1 = $('#title>h1');
$(window).ready(function(){
  var s1 = "WELCOME.";
  var s2= "Projects";

  print(0,s1);
  print(0,s2);
});

function print(i,st){
  setTimeout(function(){
    h1.text(st.substr(0,i));
    if(i<8){
      print(i+1,st);
    }
  },250);
}

我确实尝试过使用Promise:How should I call 3 functions in order to execute them one after the other? 但没有成功。它给出了结果未找到的错误,我无法弄明白。

var h1 = $('#title>h1');
$(window).ready(function(){
  var s1 = "WELCOME.";
  var s2= "Projects";

  new Promise(function(fulfill,reject){
    print(0,s1);
    fulfill(result);
  }).then(function(result){
    print(0,s2);
  });

});

这是我从stackoverflow问题得到的,我得到的是:

    Uncaught (in promise) ReferenceError: result is not defined
        at projects.js:8
        at new Promise ()
        at HTMLDocument. (projects.js:6)
        at j (jquery-3.2.1.min.js:2)
        at k (jquery-3.2.1.min.js:2)

CODEPEN:https://codepen.io/anon/pen/QaBYQz

2 个答案:

答案 0 :(得分:1)

var h1 = $('#title>h1');
$(window).ready(function() {
  var s1 = "WELCOME.";
  var s2 = "Projects";
  print(0, s1).then(()=>print(0, s2));;
});

function print(i, st, p) {
  return new Promise(done => {
    p = p || done;
    if(i > st.length) return p();
    setTimeout(function() {
      h1.text(st.substr(0, i));
      print(i + 1, st, p);
    }, 250);
  });
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id=title>
  <h1></h1>
</div>

您需要解决首次调用print时创建的第一个承诺。当你以递归方式调用print时,你正在创建新的承诺,所以如果你只是在打印最后一个字母时调用done,那么你只会解决最后的承诺。所以我创建了一个新参数,该函数可以用来递归地将第一个promises done函数传递给过去的promise。

第一次调用该函数时,p未定义,使用p = p || done;我们只将p的值分配给done 如果p未定义。因此,当整个单词被打印时(即i > st.lengthp仍将是第一个done函数。通过调用return p();,我们解析第一个函数并结束执行。

答案 1 :(得分:0)

您可以将其重写为使用承诺:

var h1 = $('#title>h1');

function onReady() {
  return new Promise(function(resolve) {
    $(window).ready(function(){
      var s1 = "WELCOME.";
      var s2= "Projects";
      resolve([s1, s2]);
    });
  });
}

onReady().then(function(res) {
  print(0, res[0]);
  print(0, res[1]);
});


function print(i,st){
  setTimeout(function(){
    h1.text(st.substr(0,i));
    if(i<8){
      print(i+1,st);
    }
  },250);
}