2011-09-26 34 views
6

Tôi có một lớp học, ChatRoom, mà chỉ có thể làm sau khi nó nhận được một yêu cầu HTTP dài chạy (nó có thể mất 1 giây hoặc 30 giây). Vì vậy, tôi cần phải trì hoãn hiển thị cho đến khi ChatRoom.json không phải là rỗng.không đồng bộ chậm JS cho đến khi một điều kiện được đáp ứng

Trong đoạn mã dưới đây, tôi đang sử dụng Đóng cửa Thư viện của goog.async.ConditionalDelay. Nó hoạt động, nhưng là có một cách tốt hơn (có thể không cần thư viện đóng cửa) để làm điều này?

ChatRoom.prototype.json = null; // received after a long-running HTTP request. 

ChatRoom.prototype.render = function() { 
    var thisChatRoom = this; 

    function onReady() { 
     console.log("Received JSON", thisChatRoom.json); 
     // Do rendering... 
    } 

    function onFailure() { 
     alert('Sorry, an error occurred. The chat room couldn\'t open'); 
    } 

    function isReady() { 
     if (thisChatRoom.json != null) { 
      return true; 
     } 
     console.log("Waiting for chat room JSON..."); 
     return false; 
    } 

    // If there is a JSON request in progress, wait until it completes. 
    if (isReady()) { 
     onReady(); 
    } else { 
     var delay = new goog.async.ConditionalDelay(isReady); 
     delay.onSuccess = onReady; 
     delay.onFailure = onFailure; 
     delay.start(500, 5000); 
    } 
} 

Lưu ý rằng "while (json == null) {}" không thể thực hiện được vì nó sẽ đồng bộ (chặn tất cả thực thi JS khác).

+2

Tại sao bạn không sử dụng gọi lại từ yêu cầu HTTP? – SLaks

+0

Tôi không thể sử dụng gọi lại đó vì kết xuất có thể được gọi trước khi trả về JSON hoặc 10 phút sau khi trả về. Về cơ bản, tôi muốn có thể gọi render() tại bất kỳ thời điểm nào tôi muốn. –

+1

Bạn vẫn có thể sử dụng gọi lại. Trong 'render', kiểm tra xem JSON đã được trả về chưa, và nếu nó chưa được trả lại, hãy thêm vào một mảng các cuộc gọi lại. Hoặc chỉ cần sử dụng các đối tượng Trì hoãn mới của jQuery, điều này thực hiện điều này cho bạn. – SLaks

Trả lời

20

Hãy xem xét điều này:

(function wait() { 
    if (chatroom.json) { 
     chatroom.render(); 
    } else { 
     setTimeout(wait, 500); 
    } 
})(); 

này sẽ kiểm tra mỗi nửa thứ hai.

Live Demo:http://jsfiddle.net/kBgTx/

-1

Câu trả lời tôi đã đưa ra là như thế này:

var count = 0; 
// Number of functions that need to run. This can be dynamically generated 
// In this case I call check(data, cb) a total of 3 times 
var functionNum = 3; 
function toCallAfter(){ 
    console.log('I am a delayed function'); 
} 

Tôi có điều này cho một chức năng kiểm tra chạy một lần đều đặn và hai lần trong một vòng lặp:

check(data, function(err){ // check is my asynchronous function to check data integrity 
    if (err){ 
     return cb(null, { // cb() is the return function for the containing function 
      errCode: 'MISSINGINFO', 
      statusCode: 403, 
      message : 'All mandatory fields must be filled in' 
     }); 
    } // This part here is an implicit else 
    count++; // Increment count each time required functions complete to 
      // keep track of how many function have completed 
    if (count === functionNum) { 
     return anon(); 
    } 
    return; 
}); 
// Run twice more in a loop 
for(var i = 0; i < 2; i++) { 
    check(data, function(err) { // calls check again in a loop 
     if (err){ 
      return cb(null, { 
       errCode: 'MISSINGINFO', 
       statusCode: 403, 
       message : 'All mandatory fields must be filled in' 
      }); 
     } 
     count++; 
     if (count === functionNum) { 
      return toCallAfter(); 
     } 
     return; 
    }); 
} 

Cuối cùng, tôi muốn chỉ ra một lỗi hiệu suất đáng kể trong câu trả lời thay thế (và cực kỳ phổ biến) er:

(function wait() { 
    if (chatroom.json) { 
     chatroom.render(); 
    } else { 
     setTimeout(wait, 500); 
    } 
})(); 

Trong trường hợp này, bạn là chủ yếu giữ trình duyệt hoặc máy chủ (Nếu sử dụng Node.js) làm con tin trong 500 mili giây cho từng tấm séc đó là một thời gian vô cùng dài cho một máy tính. Có nghĩa là một hit hiệu suất rất lớn. Giải pháp của tôi về việc theo dõi trực tiếp các chức năng được yêu cầu hoàn thành là miễn phí khỏi các hạn chế thời gian và sẽ chạy ngay lập tức ngay sau khi tất cả các chức năng được hoàn thành.

+0

500 mili giây là cuộc đời có, nhưng giữ con tin chủ đề JS mà bạn không có. Các hàm không đồng bộ trong javascript không phải là chặn luồng, chúng được xếp hàng đợi để thực hiện tại một số điểm trong tương lai. Câu trả lời được chấp nhận là phổ biến vì nó là javascript thành ngữ và có hiệu suất như bạn có thể thực hiện khi bạn không có sự kiện "sẵn sàng" mà bạn có thể trả lời. –

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