在 AJAX 成功回調中啟動定時器執行函數時,若定時器 ID 與計數器變量聲明在函數內部,會導致回調函數無法訪問,無法清除定時器或控制次數。本文通過實例講解變量作用域問題及正確解決方案。
function ajax() {
// ... AJAX 請求
if (status == "success") {
var i = 10; // 局部變量
var intervalid = setInterval(fun, 1000); // 局部變量
}
}
function fun() {
// 無法訪問 i 和 intervalid
if (i <= 0) clearInterval(intervalid); // ReferenceError
i--;
}
var i 和 var intervalid 在 ajax() 函數作用域內fun() 定義在全局作用域,無法訪問外層函數的局部變量ajax() 都會創建新的變量,舊定時器無法清除
var intervalid, i; // 全局聲明
function ajax() {
// ...
if (status == "success") {
i = 10; // 重置計數
intervalid = setInterval(fun, 1000);
}
}
function fun() {
if (i <= 0) {
clearInterval(intervalid);
return;
}
// 執行邏輯
i--;
}
function createTimer(callback, interval, count) {
let remaining = count;
const id = setInterval(() => {
if (remaining <= 0) {
clearInterval(id);
return;
}
callback();
remaining--;
}, interval);
return id;
}
// 使用
if (status == "success") {
createTimer(fun, 1000, 10);
}
const timer = {
id: null,
count: 10,
start() {
this.id = setInterval(() => this.tick(), 1000);
},
tick() {
if (this.count <= 0) {
clearInterval(this.id);
return;
}
fun();
this.count--;
}
};
timer_)clearInterval 防止內存洩漏if (timerId) clearInterval(timerId)