gpt4 book ai didi

javascript - 是否可以在 JavaScript 中链接 setTimeout 函数?

转载 作者:可可西里 更新时间:2023-11-01 01:27:23 26 4
gpt4 key购买 nike

是否可以链接 setTimout 函数以确保它们依次运行?

最佳答案

这里列出了三种不同的方法:

  1. 手动嵌套 setTimeout() 回调。
  2. 使用可链接的计时器对象。
  3. setTimeout() 包装在 promise 和链式 promise 中。

手动嵌套 setTimeout 回调

当然。当第一个触发时,只需设置下一个。

setTimeout(function() {
// do something
setTimeout(function() {
// do second thing
}, 1000);
}, 1000);

可链式计时器对象

你也可以让自己成为一个小的实用对象,它可以让你真正地链接事物,让你像这样链接调用:

delay(fn1, 400).delay(fn2, 500).delay(fn3, 800);

function delay(fn, t) {
// private instance variables
var queue = [], self, timer;

function schedule(fn, t) {
timer = setTimeout(function() {
timer = null;
fn();
if (queue.length) {
var item = queue.shift();
schedule(item.fn, item.t);
}
}, t);
}
self = {
delay: function(fn, t) {
// if already queuing things or running a timer,
// then just add to the queue
if (queue.length || timer) {
queue.push({fn: fn, t: t});
} else {
// no queue or timer yet, so schedule the timer
schedule(fn, t);
}
return self;
},
cancel: function() {
clearTimeout(timer);
queue = [];
return self;
}
};
return self.delay(fn, t);
}

function log(args) {
var str = "";
for (var i = 0; i < arguments.length; i++) {
if (typeof arguments[i] === "object") {
str += JSON.stringify(arguments[i]);
} else {
str += arguments[i];
}
}
var div = document.createElement("div");
div.innerHTML = str;
var target = log.id ? document.getElementById(log.id) : document.body;
target.appendChild(div);
}


function log1() {
log("Message 1");
}
function log2() {
log("Message 2");
}
function log3() {
log("Message 3");
}

var d = delay(log1, 500)
.delay(log2, 700)
.delay(log3, 600)

将 setTimeout 包装在 Promise 和链式 Promise 中

或者,由于现在是 ES6+ 中的 promise 时代,这里是使用 promise 的类似代码,我们让 promise 基础设施为我们进行排队和排序。您最终可以使用这样的用法:

Promise.delay(fn1, 500).delay(fn2, 700).delay(fn3, 600);

这是背后的代码:

// utility function for returning a promise that resolves after a delay
function delay(t) {
return new Promise(function (resolve) {
setTimeout(resolve, t);
});
}

Promise.delay = function (fn, t) {
// fn is an optional argument
if (!t) {
t = fn;
fn = function () {};
}
return delay(t).then(fn);
}

Promise.prototype.delay = function (fn, t) {
// return chained promise
return this.then(function () {
return Promise.delay(fn, t);
});

}

function log(args) {
var str = "";
for (var i = 0; i < arguments.length; i++) {
if (typeof arguments[i] === "object") {
str += JSON.stringify(arguments[i]);
} else {
str += arguments[i];
}
}
var div = document.createElement("div");
div.innerHTML = str;
var target = log.id ? document.getElementById(log.id) : document.body;
target.appendChild(div);
}

function log1() {
log("Message 1");
}

function log2() {
log("Message 2");
}

function log3() {
log("Message 3");
}

Promise.delay(log1, 500).delay(log2, 700).delay(log3, 600);

您提供给这个版本的功能可以是同步的,也可以是异步的(返回一个 promise )。

关于javascript - 是否可以在 JavaScript 中链接 setTimeout 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6921275/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com