settimeout 并等待是否已设置超时
settimeout and wait if timeout already set
如何为 settimeout 函数创建队列。
我想创建带有 settimeout 的函数以在 2 秒后打印控制台,但是如果相同的 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
您可以将额外的呼叫保存到队列中,然后在计时器结束时处理它:
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);
您可以使用 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);
});
您可以为此使用 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);
您可以创建一个函数队列,每个函数将执行一个 setTimeout
。然后,当一个setTimeout
被执行时,你可以得到队列的下一个函数an被执行。
下面是一个完整的工作示例:
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>
如何为 settimeout 函数创建队列。
我想创建带有 settimeout 的函数以在 2 秒后打印控制台,但是如果相同的 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
您可以将额外的呼叫保存到队列中,然后在计时器结束时处理它:
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);
您可以使用 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);
});
您可以为此使用 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);
您可以创建一个函数队列,每个函数将执行一个 setTimeout
。然后,当一个setTimeout
被执行时,你可以得到队列的下一个函数an被执行。
下面是一个完整的工作示例:
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>