如何顺序或同步执行功能

时间:2018-09-13 07:47:07

标签: javascript jquery html promise

我有4个要依次执行的功能。

尤其是第4个功能仅应在所有前三个功能都完成后才执行。

我尝试使用回叫,但是可以肯定我没有正确使用它。如何使其顺序。

我听说过JavaScript中的then函数,但是看起来它只能与ECMAScript 6一起使用(不确定),但是当我在脚本中尝试使用它时会出现未定义的错误。

function longRunningFunction(callBack) {

  setTimeout(function() {
    $('#div1').html('Div1 Done');
  }, 5000);
  setTimeout(function() {
    $('#div2').html('Div2 Done');
  }, 5000);
  setTimeout(function() {
    $('#div3').html('Div3 Done');
  }, 5000);

  callBack();

}
longRunningFunction(function() {
  setTimeout(function() {
    $('#div4').html('But changes 1st!');
  }, 3000);
});
#div4 {
  font-weight: bold;
  color: red;
}

#div1 {
  margin-top: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="div4">
  My content should be changes at last!
</div>
<div id="div1">
  Div1
</div>
<div id="div2">
  Div2
</div>
<div id="div3">
  Div3
</div>

4 个答案:

答案 0 :(得分:2)

您可以使用Promises来实现。
为将要发生的每个异步更改设置一个承诺,并等待它们通过Promise#all完成:

Promise.all([p1, p2, p3]).then(() => {
  callBack();
});

演示:

function longRunningFunction(callBack) {

  let p1 = new Promise((resolve, reject) => {
    setTimeout(function() {
      $('#div1').html('Div1 Done');
      resolve();
    }, 5000);
  });

  let p2 = new Promise((resolve, reject) => {
    setTimeout(function() {
      $('#div2').html('Div2 Done');
      resolve();
    }, 5000);
  });

  let p3 = new Promise((resolve, reject) => {
    setTimeout(function() {
      $('#div3').html('Div3 Done');
      resolve();
    }, 5000);
  });

  Promise.all([p1, p2, p3]).then(() => {
    callBack();
  });
}
longRunningFunction(function() {
    $('#div4').html('But changes 1st!');
});
#div4 {
  font-weight: bold;
  color: red;
}

#div1 {
  margin-top: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="div4">
  My content should be changes at last!
</div>
<div id="div1">
  Div1
</div>
<div id="div2">
  Div2
</div>
<div id="div3">
  Div3
</div>

答案 1 :(得分:1)

您具有关于setTimeout的x4函数,因此您可以将简单的函数whit promise和async / await功能组合在一起:

只需将() => console.log()替换为() => $('#div1').html('Div1 Done');

function sequentialTimeout(time, func){
  return new Promise(resolve => setTimeout(() => resolve(func()), time));
}

async function sequence(){
  await sequentialTimeout(500, () => console.log('1'))
  await sequentialTimeout(500, () => console.log('2'))
  await sequentialTimeout(500, () => console.log('3'))
  sequentialTimeout(500, () => console.log('4'))
}

sequence()

答案 2 :(得分:1)

您可以使用Promises,就像另一个答案所说的那样。但是,如果您认为对于如此简单的用例(可以说是这样)而言,这是太多的“繁琐的工作”,则可以为每个成功的超时设置一个标志,然后在所有设置都成功时触发回调。以下是一种方法:

function longRunningFunction(callBack) {

  var done = [false, false, false];

  function checkIfDone(cb) {
    if (done[0] && done[1] && done[2]) {
      cb();
    }
  }

  setTimeout(function() {
    $('#div1').html('Div1 Done');
    done[0] = true;
    checkIfDone(callBack);
  }, 5000);
  setTimeout(function() {
    $('#div2').html('Div2 Done');
    done[1] = true;
    checkIfDone(callBack);
  }, 5000);
  setTimeout(function() {
    $('#div3').html('Div3 Done');
    done[2] = true;
    checkIfDone(callBack);
  }, 5000);
}
longRunningFunction(function() {
  setTimeout(function() {
    $('#div4').html('But changes 1st!');
  }, 3000);
});

答案 3 :(得分:-3)

您可以尝试使用发电机

function* generateSequence() {
  yield 1;
  yield 2;
  return 3;
}

let generator = generateSequence();

let one = generator.next();

alert(JSON.stringify(one)); // {value: 1, done: false}