2012-12-24 28 views
9

Nền của tôi là các ngôn ngữ hướng đối tượng được biên dịch truyền thống như lập trình C++ và .NET, và bây giờ tôi đang xem xét một chút JavaScript cho một dự án mới. Tôi đã thử với AJAX và xuất hiện một khía cạnh khó hiểu về cách thức các đối tượng được trình duyệt quản lý.Làm thế nào các đối tượng xmlhttprequest được tạo, hợp nhất và hủy trong Javascript

[Chỉnh sửa # 2] - Thay đổi trong kịch bản nội dung hoạt động

Tôi có một trang thực hành với ba nút mà mỗi lần cập nhật một <textarea> sử dụng XMLHttpRequest đối tượng:

  1. Nút 1 cập nhật TextArea1 với văn bản nội dung từ slowtime.php
  2. Nút 2 cập nhật TextArea2 với nội dung văn bản từ slowtime.php
  3. Nút 3 cập nhật TextArea3 với nội dung văn bản từ fasttime.php

đâu slowtime.phpfasttime.php được kịch bản đơn giản mà trả về một trang văn bản/HTML với hai timestamps: một khi trang tải, sau một thời gian đã trôi qua.

Mỗi nút hoạt động chính xác khi được nhấp vào từng nút một. Nếu tôi nhấp vào nút 2 và sau đó nút 3 trước khi yêu cầu đầu tiên hoàn tất, bản cập nhật vẫn hoạt động như mong đợi.

Nếu tôi nhấp vào Nút 1 và sau đó Nút 2 trước khi yêu cầu đầu tiên hoàn tất, TextArea1 và TextArea2 sẽ nhận được các giá trị chính xác; tuy nhiên, các cuộc gọi sự kiện onreadystatechange sự kiện xảy ra cùng một lúc, tức là phản hồi đầu tiên bị trễ và chỉ được xử lý khi cuộc gọi thứ hai đến.

Mã mẫu

website

<!DOCTYPE html> 
<html> 
<head> 
<script> 
function loadXMLDoc(url,target) 
{ 
var xmlhttp; 
xmlhttp=new XMLHttpRequest(); 

xmlhttp.onreadystatechange=function() 
    { 
    if (xmlhttp.readyState==4 && xmlhttp.status==200) 
    { 
    document.getElementById(target).value=xmlhttp.responseText; 
    } 
    } 
xmlhttp.open("POST",url,true); 
xmlhttp.send(); 
} 
</script> 
</head> 

<body> 
<form> 

<input type="button" value="Button 1" onClick="loadXMLDoc('slowtime.php','TextArea1')"/> 
<input type="button" value="Button 2" onClick="loadXMLDoc('slowtime.php','TextArea2')"/> 
<input type="button" value="Button 3" onClick="loadXMLDoc('fasttime.php','TextArea3')"/> 

<div><textarea id="TextArea1"></textarea></div> 
<div><textarea id="TextArea2"></textarea></div> 
<div><textarea id="TextArea3"></textarea></div> 

</form> 
</body> 
</html> 

PHP Code (slowtime.php)

<?php 
    echo date('h:i:s') . "\n"; 
    sleep(5); 
    echo date('h:i:s') . "\n"; 
?> 

Câu hỏi [Revised]

Trình duyệt quản lý các đối tượng XMLHttpRequest như thế nào? Nhấn các nút 2 và 3 cho biết mỗi lần nhấn sẽ khởi tạo một đối tượng mới và mỗi bộ lọc này có các trình xử lý sự kiện độc lập. Nếu các đối tượng sống qua cuộc gọi hàm ban đầu (vì trình xử lý sự kiện của chúng tồn tại) khi chúng được xóa khỏi bộ nhớ/bị hủy?

Nếu XMLHttpRequests là các đối tượng riêng biệt, việc gửi yêu cầu thứ hai đến cùng một URL ảnh hưởng đến thời gian phản hồi của lần đầu tiên như thế nào? Đây có phải là vấn đề phía máy chủ không?

+0

Trong hàm 'xmlhttp.onreadystatechange', bạn có nên sử dụng' this.responseText' thay vì 'xmlhttp.responseText' không? –

+1

@ JoshuaD.Boyd Điều đó không nên làm gì khác vì biến 'xmlhttp' nằm trong phạm vi cục bộ bên trong' loadXMLDoc'. – Tyilo

+0

thay đổi tất cả các tham chiếu đến 'xmlhttp' thành' this' trong hàm 'onreadystatechange' cũng hoạt động, và cũng tạo ra cùng một hành vi – nicholas

Trả lời

2

ngữ cảnh để XMLHttpRequest không bao giờ bị xóa trừ khi xóa được gọi rõ ràng trên đối tượng. Trong trường hợp này: xmlhttp. Bạn thực sự nên theo dõi bằng cách nào đó var và làm sạch nó lên nếu bạn muốn ứng dụng của bạn chạy nạc và sạch sẽ. Javascript ban đầu được thiết kế cho các trang web, do đó nó có xu hướng để mọi thứ chạy tự nhiên trừ khi bạn tự ngăn chặn nó.

Nếu không, có thể một khi đối tượng không còn sử dụng được bởi bất kỳ chức năng nào khác hoặc có bất kỳ cuộc gọi còn lại nào, trình thu gom rác của trình duyệt sẽ loại bỏ đối tượng.

Đối với vấn đề của bạn với các sự kiện xảy ra cùng một lúc, tôi không thể tự mình tạo lại vấn đề, điều này khiến tôi tin rằng bạn gặp sự cố với cấu hình php của mình. Có thể máy chủ của bạn không cho phép nhiều tập lệnh chạy cùng một lúc không?

Dưới đây là ví dụ của bạn trên máy chủ của tôi, với một vài thay đổi nhỏ: http://www.seijinohki.net/test.php

+0

Cảm ơn bạn đã đăng mã trên một máy chủ thử nghiệm khác. Khi tôi kiểm tra trang web của bạn trong Chrome hoặc Safari, tôi nhận được kết quả tương tự như rambo, ở trên - cả hai vùng văn bản đều có cùng giá trị. Trong khi đó, Firefox, IE9 và Silk thì không. Trang của bạn không hoạt động ở tất cả trong trình duyệt di động Maxthon. – nicholas

+0

cũng sau nhiều thời gian, bệnh chấp nhận điều này như là câu trả lời vì nó trực tiếp địa chỉ bối cảnh các yêu cầu.một cuộc thảo luận thú vị và ít nhất là hiện tại, việc phát triển web/trình duyệt/v.v ... vẫn là bất cứ điều gì ngoài thống nhất trong cách thực hiện các tập lệnh. – nicholas

1

Đây là vấn đề trình duyệt.

  • Chrome 23 & 26 hoạt động theo cách này.
  • Opera 12 doesnt
  • IE 9 doesnt
  • Firefox 17 doesnt

Nếu bạn thực hiện các url độc đáo, ví dụ như slowtime.php?1slowtime.php?2 sau đó Chrome không còn cư xử theo cách này.

btw- trong chrome thử nghiệm của tôi cập nhật cả hai văn bản có cùng giá trị - các giá trị từ yêu cầu đầu tiên. và cả hai đều cập nhật khi yêu cầu đầu tiên kết thúc, không phải khi lần kết thúc thứ hai. đây chắc chắn là một lỗi vì nó chỉ đơn giản là sai. Tôi đã xác minh qua nhật ký máy chủ web mà yêu cầu thứ 2 không bao giờ được gửi.

+0

Khi tôi thử nghiệm với Chrome hoặc Safari trên máy chủ của kokorohakai, tôi thấy như vậy kết quả bạn làm - cả hai vùng văn bản đều có cùng giá trị và được tính thời gian với yêu cầu đầu tiên. Trong khi đó trên máy chủ thử nghiệm của tôi (localhost), tôi nhận được hai giá trị khác nhau, được hẹn giờ với giá trị thứ hai. Điều này khiến tôi tin rằng câu trả lời rất phức tạp, thực sự và dựa trên cả hành vi của trình duyệt và máy chủ. – nicholas

+0

@nicholas nhật ký máy chủ cục bộ của bạn có cho biết hai yêu cầu không? vẫn còn, thực tế là chrome chỉ gửi một yêu cầu trong thử nghiệm của tôi cho thấy một lỗi trong nó (hoặc một tính năng lạ). – goat

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