簡體   English   中英

Javascript:settimeout 遞歸無限堆棧增加?

[英]Javascript: settimeout recursion endless stack increase?

我的目標是使用 HTML/CSS/JS 制作背景圖片的幻燈片。 我發現的許多解決方案都促進了這樣的事情:

my_recursion();

function my_recursion () {
 // cycle the Background image ...
 setTimeout(my_recursion, 3000);
}

我認為這是不好的風格是錯誤的嗎? 我希望在例如周期 1000 時,所有其他 999 個 my_recursion 實例仍然打開/在堆棧上? 這不會創建消耗越來越多內存的無限堆棧嗎?

或者是否涉及某種智能,例如“如果一個函數在最后調用自己,則第 (n-1) 個函數將被銷毀,包括在其中分配的所有變量”?

這不會導致無休止的堆棧增加,因為 setTimeout 的工作方式,恕我直言,它的風格還不錯。

setTimeout不保證代碼會在給定的超時后直接運行。 相反,在超時之后,它會將回調推送到“隊列”上,當堆棧為空時將對其進行處理。 所以它只會在 my_recursion 返回並且堆棧為空時運行。

如果一個函數在最后調用自己 (...)

my_recursion不會在任何地方調用自己。 它只是將自己作為參數傳遞給setTimeout 之后,它會繼續執行,之后直接返回,並從堆棧中彈出。

本演示文稿解釋了堆棧和事件隊列。

在您的問題中,您的函數沒有任何參數。 在實際實現中,我希望您計划使用它們。

 const cycleBackground = (elem, bgs = [], ms = 1e3, i = 0) => ( elem.setAttribute ('style', bgs[i]) , setTimeout ( cycleBackground // function to schedule , ms // when to schedule, ms from now , elem // user-specified element to change , bgs // user-specified backgrounds , ms // user-specified delay , (i + 1) % bgs.length // next background index ) ) const backgrounds = [ "background-color: red;" , "background-image: linear-gradient(45deg, cyan 0%, purple 75%);" , "background-color: green;" ] // call site cycleBackground ( document.body // element to target , backgrounds // list of backgrounds , 3e3 // delay, 3 seconds )
 p { text-align: center; font-size: 3vw; font-weight: bold; color: white; }
 <p>Wait 3 seconds...</p>

代碼沒問題。 它會破壞所有變量,因為當您第一次調用它時。 它為下一個function設置了setTimeout()並最后返回。 你的函數不會return下一個。

my_recursion();

function my_recursion () {
 // cycle the Background image ...
 setTimeout(my_recursion, 3000); //Sets timeout for next function.
 //returns undefined here
} 

添加到https://stackoverflow.com/a/54443904/11022136 想提供一些證據。 在節點 14 上運行以下命令。

測試.js:

let i = 10;
const canThisOverflow = () => {
    i--;
    console.trace();
    if (i > 0) setTimeout(canThisOverflow, 1);
}
canThisOverflow();

輸出:堆棧大小不增加

Trace
    at canThisOverflow (/Users/arjunmalik/Shipsy/query-builder/test.js:4:10)
    at Object.<anonymous> (/Users/arjunmalik/Shipsy/query-builder/test.js:7:1)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
    at internal/main/run_main_module.js:17:47
Trace
    at Timeout.canThisOverflow [as _onTimeout] (/Users/arjunmalik/Shipsy/query-builder/test.js:4:10)
    at listOnTimeout (internal/timers.js:554:17)
    at processTimers (internal/timers.js:497:7)
Trace
    at Timeout.canThisOverflow [as _onTimeout] (/Users/arjunmalik/Shipsy/query-builder/test.js:4:10)
    at listOnTimeout (internal/timers.js:554:17)
    at processTimers (internal/timers.js:497:7)

測試2.js:

let i = 10;
const canThisOverflow = () => {
    i--;
    console.trace();
    if (i > 0) canThisOverflow();
}
canThisOverflow();

輸出:堆棧大小增加

Trace
    at canThisOverflow (/Users/arjunmalik/Shipsy/query-builder/test2.js:4:10)
    at Object.<anonymous> (/Users/arjunmalik/Shipsy/query-builder/test2.js:7:1)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
    at internal/main/run_main_module.js:17:47
Trace
    at canThisOverflow (/Users/arjunmalik/Shipsy/query-builder/test2.js:4:10)
    at canThisOverflow (/Users/arjunmalik/Shipsy/query-builder/test2.js:5:13)
    at Object.<anonymous> (/Users/arjunmalik/Shipsy/query-builder/test2.js:7:1)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
    at internal/main/run_main_module.js:17:47
Trace
    at canThisOverflow (/Users/arjunmalik/Shipsy/query-builder/test2.js:4:10)
    at canThisOverflow (/Users/arjunmalik/Shipsy/query-builder/test2.js:5:13)
    at canThisOverflow (/Users/arjunmalik/Shipsy/query-builder/test2.js:5:13)
    at Object.<anonymous> (/Users/arjunmalik/Shipsy/query-builder/test2.js:7:1)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
    at internal/main/run_main_module.js:17:47

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM