2012-01-08 35 views
17

Tôi cần chạy một hàm javascript sau mỗi 10 giây.Javascript setInterval không hoạt động

tôi hiểu được cú pháp phải làm việc như sau nhưng tôi không nhận được bất kỳ thành công:

function funcName() { 
    alert("test"); 
} 

var func = funcName(); 
var run = setInterval("func",10000) 

Nhưng điều này không hoạt động. Bất kỳ giúp đỡ?

+0

Bạn nên xem bảng điều khiển lỗi của trình duyệt của bạn nói gì trong những trường hợp này. – Bojangles

+0

Bạn có biết điều gì sẽ xảy ra khi bạn chuyển 'func '' thành 'setInterval' và giá trị' func' có? Nó luôn hữu ích khi đọc [một số tài liệu] (https://developer.mozilla.org/en/window.setInterval). –

+0

Việc truyền một chuỗi tới 'setInterval()' (thường là một ý tưởng tồi ở nơi đầu tiên) khiến cho nó thực hiện một 'eval (" func ")'.Đó là cơ bản giống như một dòng javascript như thế này: 'func;' mà không có gì. Như một chuỗi, bạn phải thực sự thực thi hàm như 'setInterval (" func() ", 10000)', nhưng tốt hơn hết là chỉ cần truyền tên hàm thực tế như 'setInterval (funcName, 10000)' và không bao giờ ép nó vào sử dụng 'eval()' ngay từ đầu. – jfriend00

Trả lời

95

Rất nhiều câu trả lời khác đang tập trung vào một mẫu hoạt động, nhưng các giải thích của họ không thực sự rất kỹ lưỡng về lý do mã hiện tại của bạn không hoạt động.

Mã của bạn, để tham khảo:

function funcName() { 
    alert("test"); 
} 

var func = funcName(); 
var run = setInterval("func",10000) 

Hãy chia nhỏ ra thành khối. Chức năng của bạn funcName là tốt. Lưu ý rằng khi bạn gọi funcName (nói cách khác, bạn chạy nó), bạn sẽ được cảnh báo "test". Nhưng lưu ý rằng funcName() - dấu ngoặc đơn có nghĩa là "gọi" hoặc "chạy" hàm - không thực sự trả về một giá trị. Khi một hàm không có giá trị trả về, hàm này mặc định là giá trị được gọi là undefined.

Khi bạn gọi một hàm, bạn nối thêm danh sách đối số của nó vào cuối trong dấu ngoặc đơn. Khi bạn không có bất kỳ đối số nào để vượt qua hàm, bạn chỉ cần thêm dấu ngoặc đơn trống, chẳng hạn như funcName(). Nhưng khi bạn muốn tham khảo chính hàm đó, và không gọi nó, bạn không cần các dấu ngoặc đơn vì các dấu ngoặc đơn chỉ ra để chạy nó.

Vì vậy, khi bạn nói:

var func = funcName(); 

Bạn đang thực sự khai báo một biến func mà có một giá trị của funcName(). Nhưng chú ý đến dấu ngoặc đơn. funcName() thực sự là giá trị trả lại của funcName. Như tôi đã nói ở trên, vì funcName không thực sự trả về bất kỳ giá trị nào, giá trị mặc định là undefined. Vì vậy, nói cách khác, biến của bạn func thực sự sẽ có giá trị undefined.

Sau đó, bạn có dòng này:

var run = setInterval("func",10000) 

Chức năng setInterval nhận hai đối số.Đầu tiên là hàm được chạy thường xuyên, và thứ hai là số mili giây giữa mỗi lần hàm được chạy.

Tuy nhiên, đối số đầu tiên thực sự phải là hàm, không phải là chuỗi. Nếu đó là một chuỗi, thì công cụ JavaScript sẽ sử dụng eval trên chuỗi đó thay thế. Vì vậy, nói cách khác, setInterval của bạn đang chạy mã JavaScript sau:

func 
// 10 seconds later.... 
func 
// and so on 

Tuy nhiên, func chỉ là một biến (với giá trị undefined, nhưng đó là loại không thích hợp). Cứ mười giây một lần, công cụ JS sẽ đánh giá biến số func và trả về undefined. Nhưng điều này không thực sự làm bất cứ điều gì. Ý tôi là, về mặt kỹ thuật, nó được đánh giá sau mỗi 10 giây, nhưng bạn sẽ không thấy bất kỳ hiệu ứng nào từ đó.

Giải pháp là cung cấp cho setInterval một hàm để chạy thay vì chuỗi. Vì vậy, trong trường hợp này:

var run = setInterval(funcName, 10000); 

Lưu ý rằng tôi không cung cấp cho nó func. Điều này là do funckhông một chức năng trong mã của bạn; đó là giá trị undefined, bởi vì bạn đã gán nó funcName(). Như tôi đã nói ở trên, funcName() sẽ gọi hàm funcName và trả về giá trị trả lại của hàm. Vì funcName không trả lại bất cứ điều gì, giá trị mặc định này là undefined. Tôi biết tôi đã nói rằng nhiều lần bây giờ, nhưng nó thực sự là một khái niệm rất quan trọng: khi bạn nhìn thấy funcName(), bạn nên nghĩ rằng "giá trị trả về của funcName". Khi bạn muốn tham chiếu đến một hàm chính nó, giống như một thực thể riêng biệt, bạn nên bỏ dấu ngoặc đơn để bạn không gọi nó: funcName.

Vì vậy, một giải pháp cho mã của bạn sẽ là:

var func = funcName; 
var run = setInterval(func, 10000); 

Tuy nhiên, đó là một chút dư thừa: tại sao sử dụng func thay vì funcName?

Hoặc bạn có thể ở lại là đúng càng tốt để mã gốc bằng cách sửa đổi hai bit:

var func = funcName; 
var run = setInterval("func()", 10000); 

Trong trường hợp này, động cơ JS sẽ đánh giá func() mỗi mười giây. Nói cách khác, nó sẽ cảnh báo "test" cứ mười giây một lần. Tuy nhiên, như cụm từ nổi tiếng, eval is evil, vì vậy bạn nên cố gắng tránh cụm từ này bất cứ khi nào có thể.

Một bước nhảy khác trên mã này là sử dụng chức năng ẩn danh. Nói cách khác, một hàm không có tên - bạn chỉ cần thả nó vào mã bởi vì bạn không quan tâm nó được gọi là gì.

setInterval(function() { 
    alert("test"); 
}, 10000); 

Trong trường hợp này, vì tôi không quan tâm chức năng được gọi là gì, tôi chỉ để lại chức năng chung, chưa được đặt tên (ẩn danh) ở đó.

+4

Cảm ơn bạn đã trả lời rõ ràng! – mauzilla

2

Đó là bởi vì bạn phải vượt qua một chức năng, không phải là một chuỗi:

function funcName() { 
    alert("test"); 
} 

setInterval(funcName, 10000); 

Mã của bạn có hai vấn đề:

  • var func = funcName(); gọi hàm ngay lập tức và gán giá trị trả về.
  • Chỉ "func" không hợp lệ ngay cả khi bạn sử dụng cú pháp giống như xấu và không được chấp nhận của setInterval. Nó sẽ là setInterval("func()", 10000) để gọi hàm eval.
2

Hãy thử điều này:

function funcName() { 
    alert("test"); 
} 

var run = setInterval(funcName, 10000) 
4

Thay đổi setInterval("func",10000) hoặc là setInterval(funcName, 10000) hoặc setInterval("funcName()",10000). Trước đây là phương pháp được khuyến nghị.

Các vấn đề liên quan