settimeout并等待是否已设置超时

时间:2019-08-07 10:34:57

标签: javascript queue settimeout

如何为settimeout函数创建队列。

我想在2秒后用settimeout创建功能到打印控制台,但是如果相同的settimeout已经在等待执行,则应该在完成第一个超时后执行新的超时功能

<script>
function print_console(text,time)
{
   if(timeout is not already set)
   {
      timeout=setTimeout(function(){console.log(text);},time);
   }
   else
   {
     time=addition of time of already setted timeout + argument time
     timeout=setTimeout(function(){console.log(text);},time);
   }
}
print_console('i will print in 1000 minisec',1000);
print_console('i will print in 3000 minisec',2000);
print_console('i will print in 6500 minisec',3500);
.................
.............
</script>

我希望此功能在控制台输出屏幕上输出-

我将以1000毫秒的速度打印--- 07/08/2019 04:01:01

我将以3000毫秒的速度打印--- 07/08/2019 04:01:03

我将以6500毫秒的速度打印--- 07/08/2019 04:01:06

4 个答案:

答案 0 :(得分:1)

您可以为此使用async/await

(async () => { 
  async function print_console(text,time) {
    await new Promise((res, rej) => {
      setTimeout(() => (console.log(text), res()), time);
    });
  }

  await print_console('i will print in 1000 minisec',1000);
  await print_console('i will print in 3000 minisec',2000);
  await print_console('i will print in 6500 minisec',3500);
})();


编辑:OP希望在此范围之外调用它。然后,我将使用另一种方法,即使用IFEE将数组,标志var和函数调用者存储到函数范围中:

const print_console = (() => {
  const arr = [];
  let isProcessing = false;
  
  setInterval(() => {
    if(isProcessing) return;
    
    const next = arr.shift();
    if(next) {
      isProcessing = true;
      setTimeout(() => {
        console.log(next.text);
        isProcessing = false;
      }, next.time);
    }
  });
  
  return (text, time) => {
      arr.push({text, time});
  } 
})();


print_console('i will print in 1000 minisec',1000);
print_console('i will print in 3000 minisec',2000);
print_console('i will print in 6500 minisec',3500);

答案 1 :(得分:0)

您可以将其他呼叫保存到队列中,然后在计时器结束时进行处理:

var print_console_stack = [], print_console_timeout = null;

function print_console(text,time)
{
   if(!print_console_timeout)
   {
      print_console_timeout = setTimeout(function(){
          console.log(text);
          print_console_timeout = null; //reset this timeout

          var next = print_console_stack.shift();
          if (next) {
              print_console(next.text, next.time);
          }
      }, time);
   }
   else
   {
     print_console_stack.push({text: text, time: time});
   }
}
print_console('i will print in 1000 millisec',1000);
print_console('i will print in 3000 millisec',2000);
print_console('i will print in 6500 millisec',3500);

答案 2 :(得分:0)

您可以使用promises

function print_console(text,time){
  var p = new Promise(function(resolve, reject) {
    setTimeout(function() {
      console.log(text);
      resolve()
    }, time);
  });
  return p;
}

print_console('i will print in 1000 minisec',1000).then(function() {
  return print_console('i will print in 3000 minisec',2000);
}).then(function() {
  return print_console('i will print in 6500 minisec',3500);
});

答案 3 :(得分:0)

您可以创建一个函数队列,每个函数将执行一个setTimeout。然后,当执行setTimeout时,您可以获得执行队列的下一个功能。

遵循一个完整的工作示例:

var timeQueue = [];
function onClick() {
  print_console(`The button was clicked!`, 2000);
}

function printALot() {
   print_console(`Row 1!`, 2000);
   print_console(`Row 2!`, 5000);
   print_console(`Row 3!`, 300);
   print_console(`Row 4!`, 400);
   print_console(`Row 5!`, 2000);
   print_console(`Row 6!`, 3000);
   print_console(`Row 7!`, 400);
   print_console(`Row 8!`, 3000);
   print_console(`Row 9!`, 400);
}

function print_console(text, time) {

  let localTime = time;
  let functionToExecute = () => {
    setTimeout(() => {
      console.log(text);
      timeQueue.pop();
      execute_next_print_console();
    }, localTime);
  }
  timeQueue.push(functionToExecute);
  if(timeQueue.length === 1) {
   execute_next_print_console();
  }
 
}

function execute_next_print_console() {
  if(timeQueue.length > 0) {
    let functionToExecute = timeQueue[0];
    functionToExecute();
  }
}
<button onclick="onClick()">click me!!!!</button>
<button onclick="printALot()">Print a lot!</button>