Javascript setTimeout函数的意外行为
我有以下代码来从一个批量大小为10的元素数组中附加iframe,每个批的时间间隔为10秒。批次是一个数组,它有一个JSON对象,每个批次都有开始和结束索引。Append函数将带有代码的iframe追加到DOM 当前行为:JS等待10秒并一起调用append函数,同时一次性追加所有iframe,而不是每批等待10秒 预期行为:JS在追加每个批处理或每个追加函数调用之前等待10秒Javascript setTimeout函数的意外行为,javascript,jquery,iframe,settimeout,Javascript,Jquery,Iframe,Settimeout,我有以下代码来从一个批量大小为10的元素数组中附加iframe,每个批的时间间隔为10秒。批次是一个数组,它有一个JSON对象,每个批次都有开始和结束索引。Append函数将带有代码的iframe追加到DOM 当前行为:JS等待10秒并一起调用append函数,同时一次性追加所有iframe,而不是每批等待10秒 预期行为:JS在追加每个批处理或每个追加函数调用之前等待10秒 batches.forEach(function (x) { setTimeout(function () {
batches.forEach(function (x) {
setTimeout(function () {
append(x, elements);
console.log('appending'+x);
}, 10000);
});
知道为什么会这样吗
setTimeout
不会暂停执行,因此您的代码相当于
setTimeout(..., 10000)
setTimeout(..., 10000)
setTimeout(..., 10000)
// etc
每个超时调用都设置为在大约相同的时间执行,从现在起10秒
您必须在每次迭代中增加超时时间。像这样的
batches.forEach((x, i) => { // where "i" is the current, zero-based index
setTimeout(() => {
// etc
}, 10000 * (i + 1))
})
您可以创建一个函数来处理批处理,如下所示:
function processBatch(batches, delay){
setTimeout(function(){
// get the first element / child in batches
var batch = batches[0];
// process your batch the way you want it
console.log(batch);
// remove the already processed batch
batches.splice(0, 1);
if (batches.length > 0){
// process the remainder batches
processBatch(batches, delay)
} else {
console.log('done');
}
}, delay)
}
称之为:
var batches = [1, 2, 3, 4];
processBatch(batches, 100000);
要查看它的运行:(别忘了打开浏览器控制台)相关:您的foreach循环只是在所有元素之间循环,而不停止。所以它很快为每个元素创建了一个setTimeout。然后它们都等待10秒钟,然后一次执行所有操作。如果您希望它们在不同的时间执行,那么您必须给它们每个不同的延迟。