首页 > 解决方案 > 这个递归调用最终会导致网页崩溃吗?

问题描述

我正在使用 java 脚本为网页制作打字机效果。

const wordList = ["word 1","word 2","word 3"];
let word = wordList[0];
let temp = "";
let complete = false;
let i = 0;
let blinkTime = 650;
let type = ()=>{
    async function myDisplay(){
        let myPromise = new Promise(function (res,rej){
            setTimeout(function(){
                if(!complete){
                    temp = word.slice(0,temp.length + 1);
                }
                else{
                    temp = word.slice(0,temp.length - 1);
                }
                res(temp);
            },Math.floor(Math.random()*300 + 100));
        });
        document.getElementById("type").innerHTML = await myPromise;
    }
    myDisplay().then(function (){
        if(temp===word && !complete){
            complete = true;
            setTimeout(function(){type();},3000);
        }
        else if (temp === "" && complete){
            complete = false;
            i = (i+1)%wordList.length;
            word = wordList[i]
            type();
        }
        else{
            type();
        }
    });
}
let blink = function(){
    let myPromise = new Promise(function(res){
        setTimeout(function() {
            document.getElementById("type").style.borderRightStyle = "solid";   
        },blinkTime);
        res();
    });   
    myPromise.then(function(){
        setTimeout(function() {
            document.getElementById("type").style.borderRightStyle = "none";
            blink();    
        },2*blinkTime);
    });
}
type();
blink();
<!DOCTYPE html>
<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]>      <html class="no-js"> <!--<![endif]-->
<html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title></title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="">
    </head>
    <body>
        <!--[if lt IE 7]>
            <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
        <![endif]-->
        <span id="type"></div>
        <span id="type2"> hello there</div>
        <script src="./script/myScript.js" async defer></script>
    </body>
</html>

该程序运行得非常好,但我是 java 脚本的新手,据我所知,没有正确结束的递归调用不是一个好的编程习惯。在上面的 java 脚本代码中,type()函数和blink()函数永远不会结束它们的递归调用,这是一个可能会破坏网页的令人担忧的问题,还是我在这里遗漏了一些概念?

标签: javascripthtmlperformancefunctionrecursion

解决方案


不,这不是问题:

实际上没有(纯)递归正在进行。type调用的不是执行上下文type(同样适用于blink)。看似“递归”的调用是在另一个函数上下文中进行的:要么是给定的,要么是setTimeout给定一个 Promise 的then方法的。此类回调是异步执行的,这意味着它们是从保证调用堆栈为的状态开始执行的。

永远不会出现 的执行上下文type等待返回的“递归”调用的情况type,因此不会出现调用堆栈容量不足的情况。


推荐阅读