是否可以顺序运行SetTimeout函数?

时间:2018-07-14 16:07:47

标签: javascript

我正在尝试创建一个将多个函数作为参数并依次执行这些函数的函数,但是每个函数都有setTimeout,通过它们可以并行执行函数。可以使其顺序吗?

  var fun1=function(){
    console.log('Started fun1');
    setTimeout(()=>{console.log('Finished fun1');},2000)
}

var fun2=function(){
    console.log('Started fun2');
    setTimeout(()=>{console.log('Finished fun2');},2000)
}


function fun3(arr){
  for(var i=0;i<arr.length;i++)
    arr[i]();
}

fun3([fun1,fun2]);

2 个答案:

答案 0 :(得分:2)

您的函数是异步的,异步函数需要某种方式来指示它们何时完成。通常,这是通过回调或Promise完成的。没有这些,就无法知道它们何时完成。如果他们兑现了承诺,您可以执行以下操作:

var fun1 = function() {
  console.log('Started fun1');
  return new Promise(resolve => {
    setTimeout(() => {
      console.log('Finished fun1');
      resolve(true)
    }, 2000)
  })

}

var fun2 = function() {
  console.log('Started fun2');
  return new Promise(resolve => {
    setTimeout(() => {
      console.log('Finished fun2');
      resolve(true)
    }, 2000)
  })
}


function fun3(arr) {
  let p = Promise.resolve()
  for (var i = 0; i < arr.length; i++){
    p = p.then(arr[i]);
  }
  return p
}

fun3([fun1, fun2]);

您可以使用reduce()来简化编写循环:

function fun3(arr){
  return arr.reduce((a, c) => a.then(c), Promise.resolve())
}

如果您可以使用async/await,则最后一个函数将更易于阅读。由于async函数返回了一个Promise,因此您还可以很容易地知道整个过程何时完成:

async function fun3(arr){
  for(var i=0;i<arr.length;i++)
    await arr[i]();
}


fun3([fun1,fun2])
.then(() => console.log("finished"))

当然,如果有可能使用简单的非异步功能,那么许多问题就会消失……您可以在功能之外的计时器中运行。

答案 1 :(得分:0)

您可以在setTimeout回调的内部 中添加下一个函数。

例如,

var fun1=function(){
    console.log('Started fun1');
    setTimeout(()=>{
        console.log('Finished fun1');
        fun2(); // Start the next timeout.
    },2000)
}

var fun2=function(){
    console.log('Started fun2');
    setTimeout(()=>{
      console.log('Finished fun2');
    },2000)
}

// This should output 'Started fun1', delay, 
// output 'Finished fun1' and then 'Started fun2',
// delay, and then finally output 'Finished fun2'.
fun1();