2010-09-03 25 views
45

Tôi muốn buộc một chương trình JavaScript phải đợi trong một số điểm cụ thể của việc thực hiện nó cho đến khi biến đã thay đổi. Có cách nào để làm điều đó? Tôi đã tìm thấy một phần mở rộng được gọi là "JavaScript tường thuật" để buộc chương trình phải đợi cho đến khi một sự kiện xảy ra. Có cách nào để tạo sự kiện mới, "sự kiện thay đổi biến" chẳng hạn như hoạt động như sự kiện onclick không.Làm cách nào để tôi có thể thực hiện một chương trình chờ thay đổi trong javascript?

Trả lời

0

Không, bạn sẽ phải tạo giải pháp của riêng mình. Giống như sử dụng mẫu thiết kế Observer hoặc một cái gì đó.

Nếu bạn không có quyền kiểm soát biến hoặc người đang sử dụng nó, tôi e rằng bạn đang phải chịu số phận. EDIT: Hoặc sử dụng giải pháp của Skilldrick!

Mike

76

một giải pháp nhanh chóng và dễ dàng đi như thế này:

var something=999; 
var something_cachedValue=something; 

function doStuff() { 
    if(something===something_cachedValue) {//we want it to match 
     setTimeout(doStuff, 50);//wait 50 millisecnds then recheck 
     return; 
    } 
    something_cachedValue=something; 
    //real action 
} 

doStuff(); 
+1

chỉnh sửa ngay bây giờ, nó sẽ kiểm tra mọi 50ms và hoạt động đối với những người không phải là kẻ ngu.nó như tôi đã nói cách nhanh chóng và dễ dàng để làm điều đó, hãy làm theo liên kết này: http://stackoverflow.com/questions/1029241/javascript-object-watch-for-all-browsers (được đăng bởi @mplungjan) để biết thêm giải pháp chống vấn đề chuyên sâu. – aularon

+0

Tôi nghĩ bạn có nghĩa là 'cái gì đó === something_cachedValue'. Sau đó, nó hoạt động: http://jsfiddle.net/pEnYC/ – Skilldrick

+0

@ Skilldrick, vâng tôi có nghĩa là, tôi đã sửa nó. Cảm ơn sự điều chỉnh:) – aularon

5

Tôi muốn giới thiệu một wrapper mà sẽ xử lý giá trị được thay đổi. Ví dụ: bạn có thể có chức năng JavaScript, như sau:

​function Variable(initVal, onChange) 
{ 
    this.val = initVal;   //Value to be stored in this object 
    this.onChange = onChange; //OnChange handler 

    //This method returns stored value 
    this.GetValue = function() 
    { 
     return this.val; 
    } 

    //This method changes the value and calls the given handler  
    this.SetValue = function(value) 
    { 
     this.val = value; 
     this.onChange(); 
    } 


} 

Và sau đó bạn có thể tạo một đối tượng để giữ giá trị bạn muốn theo dõi và cũng có chức năng sẽ được gọi khi giá trị nhận được đã thay đổi. Ví dụ, nếu bạn muốn được thông báo khi có những thay đổi giá trị, và giá trị ban đầu là 10, bạn sẽ viết mã như thế này:

var myVar = new Variable(10, function(){alert("Value changed!");}); 

Handler function(){alert("Value changed!");} sẽ được gọi (nếu bạn nhìn vào code) khi SetValue() là gọi là.

Bạn có thể nhận được giá trị như sau:

alert(myVar.GetValue()); 

Bạn có thể thiết lập giá trị như sau:

myVar.SetValue(12); 

Và ngay sau đó, một cảnh báo sẽ được hiển thị trên màn hình. Xem cách hoạt động: http://jsfiddle.net/cDJsB/

+0

Cảm ơn bạn đã trả lời, nhưng nó không phải là chính xác những gì tôi muốn. Nhìn nhận xét của tôi để aularon xin vui lòng! –

15

Trình thông dịch JavaScript là một chuỗi duy nhất, do đó biến không bao giờ thay đổi, khi mã đang chờ ở một số mã khác không thay đổi biến.

Theo tôi, đó sẽ là giải pháp tốt nhất để bọc biến trong một số loại đối tượng có chức năng getter và setter. Sau đó bạn có thể đăng ký một hàm gọi lại trong đối tượng được gọi khi hàm setter của đối tượng được gọi. Sau đó bạn có thể sử dụng hàm getter trong callback để lấy giá trị hiện tại:

function Wrapper(callback) { 
    var value; 
    this.set = function(v) { 
     value = v; 
     callback(this); 
    } 
    this.get = function() { 
     return value; 
    } 
} 

này có thể dễ dàng sử dụng như thế này:

<html> 
<head> 
<script type="text/javascript" src="wrapper.js"></script> 
<script type="text/javascript"> 
function callback(wrapper) { 
    alert("Value is now: " + wrapper.get()); 
} 

wrapper = new Wrapper(callback); 
</script> 
</head> 
<body> 
    <input type="text" onchange="wrapper.set(this.value)"/> 
</body> 
</html> 
+2

Có lẽ giải pháp tốt nhất nếu bạn có quyền kiểm soát biến ban đầu. – Skilldrick

+0

Cảm ơn bạn đã trả lời, nhưng nó không phải là chính xác những gì tôi muốn. Nhìn nhận xét của tôi để aularon xin vui lòng! –

+1

Như tôi đã giải thích các thông dịch viên JavaScript đơn luồng. Bạn không thể chặn các chủ đề và làm cho nó chờ đợi cho một số chủ đề khác để thay đổi một biến, bởi vì không có chủ đề khác có thể thay đổi một biến. Không có trình xử lý sự kiện JavaScript nào có thể được thực thi trong khi một trình xử lý sự kiện khác đã thực thi. – Reboot

1

Bạn có thể sử dụng tính:

Object.defineProperty MDN documentation

Ví dụ:

function def(varName, onChange) { 
    var _value; 

    Object.defineProperty(this, varName, { 
     get: function() { 
      return _value; 
     }, 
     set: function(value) { 
      if (onChange) 
       onChange(_value, value); 
      _value = value; 
     } 
    }); 

    return this[varName]; 
} 

def('myVar', function (oldValue, newValue) { 
    alert('Old value: ' + oldValue + '\nNew value: ' + newValue); 
}); 

myVar = 1; // alert: Old value: undefined | New value: 1 
myVar = 2; // alert: Old value: 1 | New value: 2 
Các vấn đề liên quan