javascript - 是否可以通过该函数之外的操作退出 javascript 中的递归函数?

标签 javascript function exit

我有一个脚本(在下面的示例中进行了简化),其中用户操作会启动递归函数。

用户有可能在已经启动的操作尚未完成运行时启动新的操作。

但我想确保任何新操作都停止所有以前的操作

目前实际发生的情况(您可以在下面的示例中看到)是,无论用户启动了多少新操作,之前启动的每个操作都会继续,直到完成。

我想知道(在下面的示例中)是否可以在前一个列表仅增长到 5 个项目时开始增长新列表并确保前一个列表不再增长。

var trigger = document.getElementsByTagName('p')[0];
var o = 0;

function addListItems(orderedList, listItemNumber) {

    var listItems = orderedList.getElementsByTagName('li');
    
    if (listItemNumber > 9) {
        return;
    }
    
    listItems[listItemNumber].classList.add('show');
    listItemNumber++;
    setTimeout(function(){addListItems(orderedList, listItemNumber)}, 400);
}

function startRecursiveFunction() {
    
    var orderedList = document.getElementsByTagName('ol')[o];
    var listItemNumber = 0;
    if (o < 7) {
        addListItems(orderedList, listItemNumber);
    }
    o++;
}

trigger.addEventListener('click', startRecursiveFunction, false);
p {
font-weight: bold;
cursor: pointer;
}

ol {
display: inline-block;
}

li {
opacity: 0;
}

li.show {
opacity: 1;
}
<p>Click to trigger function (up to 7 times)</p>

<ol>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ol>

<ol>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ol>

<ol>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ol>

<ol>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ol>

<ol>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ol>

<ol>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ol>

<ol>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ol>

最佳答案

您可以使用 clearTimeout 取消计划的超时事件。

注意用 *** 标记的代码的三个更改,它们都处理新的 timer 变量:

var trigger = document.getElementsByTagName('p')[0];
var o = 0;
var timer; //***

function addListItems(orderedList, listItemNumber) {

    var listItems = orderedList.getElementsByTagName('li');
    
    if (listItemNumber > 9) {
        return;
    }
    
    listItems[listItemNumber].classList.add('show');
    listItemNumber++;
    // ***
    timer = setTimeout(function(){addListItems(orderedList, listItemNumber)}, 400);
}

function startRecursiveFunction() {
    
    var orderedList = document.getElementsByTagName('ol')[o];
    var listItemNumber = 0;
    clearTimeout(timer); // ***
    if (o < 7) {
        addListItems(orderedList, listItemNumber);
    }
    o++;
}

trigger.addEventListener('click', startRecursiveFunction, false);
p {
font-weight: bold;
cursor: pointer;
}

ol {
display: inline-block;
}

li {
opacity: 0;
}

li.show {
opacity: 1;
}
<p>Click to trigger function (up to 7 times)</p>

<ol>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ol>

<ol>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ol>

<ol>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ol>

<ol>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ol>

<ol>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ol>

<ol>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ol>

<ol>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ol>

但是,我应该补充一点,这不是真正的递归:调用堆栈不会随着每次调用 addListItems 而不断增长,因为当下一个调用启动时,上一个调用已经结束setTimeout 事件:调用堆栈在此类调用之间为空。

如果这是真正的(同步)递归,您将无法对点击事件执行任何操作,因为在递归完成之前不会调用这些事件回调。

关于javascript - 是否可以通过该函数之外的操作退出 javascript 中的递归函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48736750/

相关文章:

javascript - Facebook API : user_feed is empty

javascript - jQuery 的 crossdomain.xml?

r - 仅当列存在时才执行dplyr操作

c - EASY C++(函数调用)

php - 影响关闭函数中的退出代码

bash - 有没有办法在退出时执行命令(无论脚本如何退出)?

javascript - JQuery 不将 css 应用于选定的 li

Javascript:正则表达式用于替换文本中的单词而不是单词的一部分

c - 是否可以在线程中使用退出?

javascript - JavaScript 中的 "uncaught TypeError: Object is not a function"