繁体   English   中英

如何使用 setTimeout 在递归 function 中延迟 for 循环?

[英]How do I delay a for-loop in a recursive function using setTimeout?

问题:

我正在尝试制作一个工具来帮助我在一个文件夹中组织一堆随机照片以及 HTML 文档中的一堆帖子。 我的代码工作正常,并且做了它应该做的事情。 但是有很多照片,我需要在我的 function 上放慢 for 循环。 它只工作一分钟,然后浏览器不断崩溃。 我想要做的是实现一个 setTimeout function 来减慢循环速度,这样我就可以成功地循环所有数据。 主要问题是我不知道将 setTimeout function 放在哪里或在哪里调用它。 我尝试了各种设置超时的方法,我也尝试使用异步和等待睡眠 function。 我将 HashTags (#'s) 放在我需要帮助的部分周围。 页面顶部的 setTimeout 和底部的循环。 任何帮助深表感谢。

代码:

<script>

//  **#### DELAY FUNCTION ####**
// **#### BREAKS RECURSION ####**
   
function delay(j) { 

    setTimeout(function() { 
    
    }, 2000 * j);
    
}

function loop(node){
    
    // LOOP THROUGH INDIVIDUAL NODES

    var currentElement = node.childNodes;
    
    for (var i = 0; i < currentElement.length; i++){
    
        // CHECKS FOR RECURSION

        if (!currentElement[i]){
        
            alert("CONTINUED");
            
            continue;
        }

        if (currentElement[i].childNodes.length > 0){
                
            var currElemTag = currentElement[i].tagName;
            var currElemClass = currentElement[i].className;
                
            // PHOTO AND VIDEO, HYPERLINK FILTER
                
            if (currElemTag == 'A') {
                
                var currElemHref = currentElement[i].href;
                
                if (currElemHref.includes('.jpg') == true || currElemHref.includes('.mp4') == true) {

                    
                    // MP4 - JPG HANDLER
                    
                    var outputConsole = document.getElementById('outputConsole');
                    
                    if(currElemHref.includes('.jpg') == true) {
                        var newElement = '<'+currElemTag+' href="'+currElemHref+'">'+'<img src="'+currElemHref+'"></img></A><br>';
                        outputConsole.innerHTML+=newElement+'\r\n';     
                    }
                    
                    if(currElemHref.includes('.mp4') == true) {
                        var newElement = '<'+currElemTag+' href="'+currElemHref+'">'+'<video src="'+currElemHref+'"></video></A><br>';
                        outputConsole.innerHTML+=newElement+'\r\n';     
                    }
        
                }
                
                
            }
                
            // MAIN POST
                
            else if (currElemTag == 'DIV' && currElemClass == "_2pin") {
                
                var currElemStr = currentElement[i].innerHTML;
                

                var mainPost = currElemStr.substring(
                
                    currElemStr.lastIndexOf('<div>') + 5,
                    currElemStr.lastIndexOf('</div>')
                    
                );
                
                var outputConsole = document.getElementById('outputConsole');
                var newElement = '<'+currElemTag+'>'+mainPost+'</DIV><br>';
                outputConsole.innerHTML+=newElement+'\r\n';
                
            }
                
            // SUBPOST OF SPECIFIC PHOTO
                
            else if (currElemTag == 'DIV' && currElemClass == "_3-95") {
                
                var currElemStr = currentElement[i].innerHTML;
                var outputConsole = document.getElementById('outputConsole');
                var newElement = '<'+currElemTag+'>'+currElemStr+'</DIV><br>';
                outputConsole.innerHTML+=newElement+'\r\n'; 
            
            }

            
            // POST DATE
            
            else if (currElemTag == 'DIV' && currElemClass == "_3-94 _2lem") {
                
                var currElemStr = currentElement[i].innerHTML;
                    
                var postDate = currElemStr.substring(
                
                    currElemStr.lastIndexOf('">') + 2,
                    currElemStr.lastIndexOf('</a>')
                    
                );
                    
                var outputConsole = document.getElementById('outputConsole');
                var newElement = '<'+currElemTag+'>'+postDate+'</DIV><br>';
                outputConsole.innerHTML+=newElement+'\r\n\r\n\r\n';
                
                // alert("THE DATE OF THIS POST IS: " + postDate);
                
            }
                
                
            else {
                
                var outputConsole = document.getElementById('outputConsole');
                outputConsole.innerHTML+='ELEMENT DELETED!!!'+'\r\n';
                
                // alert(currElemTag + " Named: " + currElemClass + " WILL BE DELETED!!!");

                
                
            }
            
            // #### FUNCTION LOOPS HERE ####
            // #### START DELAY ####

            delay(i);
            loop(currentElement[i]);
        }       
        
    }
    
}

将代码包装在 setTimeout 中的 for 循环中。 您还可以将 j 作为 function 参数传递。

for(var i = 0; i < currentElement.length; i++) {
   setTimeout(function() {
     // Your code
   }, 2000 * j) // Pass j as a function parameter in your loop function
}

如果可能的话,让你的loop function async ,这样你就可以在每次迭代后await 2 秒。

您可以定义delay function 以返回Promise ,这将在几秒钟后解决。

function delay(millis) {
    return new Promise(resolve => {
        setTimeout(resolve, millis);
    });
}

将您的loop function 定义为async ,您已准备好 go。

async function loop() {
    const currentElement = node.childNodes;
    for (let i = 0; i < currentElement.length; i++){
        // Do your stuff
        
        // Wait for 2 secs
        await delay(2000);
    }
}

我建议您在最后等待递归调用loop

 //... await delay(2000); await loop(...);

希望能帮助到你。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM