2013-02-14 19 views
5

Như một ví dụGiết chết một hàm JavaScript chạy vô hạn

var runInfinite = function(){ 
    while(1) 
    { 
     // Do stuff; 
    } 
}; 

setTimeout(runInfinite, 0); 

Có thể phá vỡ hình thức chức năng runInfinite này chạy vô hạn? Tôi có nghĩa là có thể giết chức năng này từ một chức năng khác mà không cần sử dụng cờ hoặc câu lệnh trả về?

+1

Tại sao bạn loại trừ bằng cách sử dụng cờ? Có vẻ như là nơi hoàn hảo để sử dụng nó. – nunespascal

+2

AFAIK, khối 'while (1)' theo nghĩa đen sẽ chặn luồng và không cho phép bất kỳ thứ gì khác chạy. Tôi không có nguồn nào khác ngoài kinh nghiệm. (hoặc có thể nó chỉ chậm đến mức có thể đóng băng hiệu quả) Nếu tôi có tài liệu, tôi sẽ đăng câu trả lời. –

+1

JavaScript (trong trình duyệt) là chuỗi đơn nên vòng lặp while _actually_ chặn luồng; và bạn không có chuỗi nào khác mà bạn có thể sử dụng để thăm dò ý kiến ​​/ đặt cờ. –

Trả lời

5

Câu trả lời là không. Vì JavaScript là đơn luồng (trừ khi bạn đang sử dụng một số triển khai ít phổ biến hơn mà tôi nghi ngờ), không có gì có thể phá vỡ vòng lặp (hoặc bất kỳ khối mã nào khác) từ bên ngoài.

+0

Vâng, nếu câu trả lời là KHÔNG. Điều đó có nghĩa là không có câu trả lời "trả về", điều đó là không thể. cho phép suy nghĩ nếu tôi tiêm nếu (isTimeoutFlag) trở lại; bên trong chức năng người dùng tại thời gian chạy .... thats có thể sửa chữa vấn đề của tôi? Đề nghị của bạn là gì? – Somnath

+0

Nó sẽ không. Bởi vì sau đó bạn sẽ phải có khả năng đặt cờ đó thành 'true' mà bạn không thể làm được, bởi vì JavaScript là một luồng đơn (trừ khi bạn thêm mã này vào tập lệnh của người dùng, điều mà bạn có thể thấy khá khó). :) Tôi khuyên bạn không nên làm điều đó chút nào - tìm một cách khác mà không cho phép người dùng viết kịch bản. – freakish

+0

Tôi sẽ bỏ nó ra. Hãy cho bạn biết guys .. – Somnath

1

Tôi vừa mới thử nghiệm trên trình duyệt của mình.

AFAIK, khối trong khi (1) theo nghĩa đen sẽ chặn chuỗi và không cho phép bất kỳ thứ gì khác chạy. Tôi không có nguồn ngoài trải nghiệm, nhưng sử dụng công cụ dành cho nhà phát triển Chrome ctrl+shift+i nhập while(1){} sẽ chặn mọi thứ khác do thực tế là trình duyệt javascript là một luồng đơn.

Tuy nhiên, nếu bạn đang sử dụng node.js, bạn có thể có khả năng đa luồng. Nếu ai đó quen thuộc đủ với node.js và sẵn sàng trả lời/chỉnh sửa, hãy thực hiện nó. Tôi chưa bao giờ sử dụng nó.

+0

Trên thực tế NodeJS là đơn luồng cũng (và không có multithreading capablitiy) vì nó được xây dựng trên V8 - cùng một công cụ JavaScript trong Chrome. – freakish

+0

http://stackoverflow.com/questions/5200821/grasping-the-node-js-alternative-to-multithreading Rõ ràng nó có thể hỗ trợ các kỹ thuật đa luồng mặc dù –

+1

Không. Bản thân động cơ đang sử dụng các chủ đề. Nhưng nó không có nghĩa là các luồng có sẵn cho một lập trình viên NodeJS. – freakish

1

Tiếng mà bạn muốn không thực sự. Nhưng có thể bạn đang làm sai. Cố gắng không sử dụng while(1) nếu có thể và ở cuối hàm gọi lại hàm nếu cờ bên ngoài được kích hoạt nhưng một số nút ngắt không được đặt hoặc trả lại nếu không

0

return có thể được sử dụng để dừng chức năng thực hiện hiện tại của nó nhưng không phải trong trường hợp của bạn.

Trong trường hợp của bạn, bạn có thể thử chức năng của mình được gói trong khối try/catch, bạn có thể tìm ra khi chức năng của bạn vô hạn, dựa trên đó bạn có thể chấm dứt thực thi hiện tại.

+0

cho phép tôi nghĩ rằng tôi có một chồng chức năng do người dùng cung cấp. Tôi chạy từng cái một. Vấn đề là tôi không thể yêu cầu người dùng đặt một lá cờ bên trong chức năng của họ. Bạn đang nói tôi để tiêm mã cho thời gian-out-quy tắc bên trong người dùng chức năng? – Somnath

+0

Tôi không tìm thấy bất kỳ ngoại lệ nào trong hàm trên. Khối try/catch sẽ giúp như thế nào? Tôi bối rối! – Somnath

2

Không có cách nào trực tiếp để "tiêu diệt" chức năng javascript đang chạy.

có thể khắc phục, mặc dù bạn cần phải thay thế while(1) loop:

var i = 0; // for testing purposes 

var toCall = "runInfinite()"; 
function runInfinite(){ 
    // do stuff 
    console.log(i++); 
    setTimeout(function(){ eval(toCall); }, 100); // or whatever timeout you want 
} 

setTimeout(function(){ eval(toCall); }, 0); // start the function 
setTimeout(function(){ toCall = ""; }, 5000); // "kill" the function 

Tôi biết sử dụng eval() được coi là xấu thực tế, tuy nhiên ý tưởng phải rõ ràng. Hàm này tự gọi (không đệ quy, do đó, setTimeout()) sử dụng biến số toCall. Khi biến này không được đặt, bạn sẽ xóa nó từ bên ngoài.

Bạn có thể bao bọc các biến và hàm này trong một lớp để bạn có thể triển khai hàm "kill" của mình.