XMLHttpRequest - 使用后是否需要释放?
XMLHttpRequest - 使用后是否需要释放?
我正在编写一个完全由AJAX驱动的浏览器应用程序(这是我生命中的第一次),这意味着:
- 它将是一个停留在浏览器中的页面,根据需要加载程序组件
- 浏览器历史记录将不存在
- 页面将不会刷新
我的问题是关于XMLHttpRequests应该怎么处理,因为我主要是C ++程序员,被教导说当你写下类似于
x = new XMLHttpRequest();
之后你需要使用delete
来删除它。
这个问题完全是关于内存管理的,这个用new
分配的对象是否会一直停留在内存中,即使它的readyState == 4已经完成了它的“循环”或者是否被释放,释放,那个什么来着?老实说,我不知道它在什么时候可以被释放,因为创建这些的脚本将位于HEAD中,并且可能在整个工作日都存在。是否应该:
- 创建一个或多个重新使用的XMLHttpRequest对象,编写应用程序以便它不需要超过这个限制,
- 或者无所谓,我可以分配任意多个新的XMLHttpRequest对象?
请在您的答案中包含在什么时候以及为什么这些对象将被删除(如果它们被删除的话),考虑到我的网页的“框架”将会保持不变。希望我已经清楚地提出了这个问题,感谢任何有见地的答案。
编辑:
考虑到一个onClick
事件处理程序的代码(为了简洁起见,我删除了很多检查意外返回值的代码),它创建XMLHttpRequest并发送它:
function submitme(){ var p = document.getElementById('p'); //要发送到服务器的文本字段 if(typeof p!='undefined' && p!=null){ if(p.value!=""){ //在这里创建XMLHttpRequest,这个函数 //返回这种类型的对象或false(如果失败) var xhr=createXmlHttpRequestObject(); if(xhr!=false){ xhr.open("POST", "blablabla.php", true); xhr.onreadystatechange=function(){ if(xhr.readyState==4){ if(xhr.status==200){ //结果将发布在下面的div中 var adiv = document.getElementById('resultdiv'); //从服务器检索到的XML xmlResponse = xhr.responseXML; //获取XML结构的文档元素(根元素) xmlDocumentElement = xmlResponse.documentElement; //获取响应文本 if(typeof adiv !='undefined' && adiv != null){ adiv.innerHTML=xmlDocumentElement.childNodes[0].firstChild.nodeValue; } }//结束xhr.status }//结束xhr.readyState };//结束xhr.onreadystatechange xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xhr.send(p.value); }//结束xhr!=false }//结束p.value!="" }//结束typeof p!='undefined' }//结束submitme()
当创建XMLHttpRequest对象实例时,如果触发此处理程序,则它将被xhr
变量引用一次,直到处理程序完成执行。在这一点上,对这个对象实例有多少个引用?如果我正确理解你们答案中的文章,答案应该是没有,浏览器只需等待此请求变为readystate == 4
,完成执行onreadystatechange
函数,然后对象就无法访问了。请确认。
XMLHttpRequest - freeing after use?
在使用JavaScript时,有一个自动内置的垃圾收集器。你可能想读一下这篇文章:this。
请你看一下我的编辑并确认我是否理解正确?
对我来说看起来是正确的。我能发现的唯一错误是第三行缺少一个)
。你还应该考虑到xhr.status
的值如果是200 <= x < 300
或者x = 304
也是有效的。查看这个链接:jsfiddle.net/57Pv7。
我接受了这个答案,因为它比Quentin的答案早了4秒,尽管它们是一样的 😉
问题出现的原因:没有在第三行的代码中加入一个缺少的括号。
解决方法:在第三行的代码中加入缺少的括号。
XMLHttpRequest - 使用后是否需要释放?
问题出现的原因:
如果每次创建新的xhr对象(不重用它们)并且将每个xhr对象捕获在相应的onreadystatechange回调的闭包中,那么xhr对象将永远不会被垃圾收集,从而导致内存泄漏。
解决方法:
为了避免这种情况,可以使用“this”来访问xhr对象(例如检查状态),并将xhr对象移出闭包。另外,还可以将onreadystatechange设置为null来清理。
代码示例:
xhr.onreadystatechange = null;
需要注意的是,使用JQuery时可能会有一些不同,但在纯JS中,不需要进行任何“nulling”操作。需要注意的是,几乎每个XHR示例都存在在处理程序函数闭包中捕获XHR对象的问题。例如,使用以下代码:
xhr = new XMLHttpRequest(); xhr.onreadystatechange = (function() { return function() { callb(xhr); }; })();
而不是使用以下代码:
callb(this);
在JQuery中,使用“this”可能会导致未定义的问题,因此在闭包中需要使用上述的捕获方式。然而,在闭包中使用“this”不会导致垃圾回收问题。如果不确定或无法进行测试,可以使用“xhr.onreadystatechange=null”作为最安全的选项。
在使用XMLHttpRequest时,需要注意释放对象以避免内存泄漏。通过使用“this”来访问xhr对象,并将xhr对象移出闭包,可以避免内存泄漏的问题。如果使用JQuery,可能需要根据具体情况进行调整,但仍然需要注意释放对xhr对象的引用。
XMLHttpRequest是一种用于在Web浏览器和服务器之间发送HTTP请求和接收响应的API。然而,有时候在使用XMLHttpRequest对象时会遇到一些问题,比如出现了问题:XMLHttpRequest - freeing after use?
问题的出现原因是在XMLHttpRequest对象仍处于打开状态时,如果该对象被垃圾回收,浏览器必须终止该请求。具体来说,以下情况将导致XMLHttpRequest对象不能被垃圾回收:
1. 当XMLHttpRequest对象的状态为OPENED并且send()标志被设置时。
2. 当XMLHttpRequest对象的状态为HEADERS_RECEIVED时。
3. 当XMLHttpRequest对象的状态为LOADING时。
解决这个问题的方法是,确保在使用完XMLHttpRequest对象后及时释放它。具体来说,需要满足以下条件之一:
1. 注册了一个或多个类型为readystatechange、progress、abort、error、load、timeout或loadend的事件监听器。
2. upload complete标志未设置,并且关联的XMLHttpRequestUpload对象注册了一个或多个类型为progress、abort、error、load、timeout或loadend的事件监听器。
通过遵循上述条件,可以保证XMLHttpRequest对象在使用完后能够被垃圾回收,避免浏览器终止请求的问题。
需要注意的是,这些规范是针对XMLHttpRequest对象在所有浏览器中的实现方式,但并不保证所有浏览器都完全按照这些规范进行实现。所以在使用XMLHttpRequest对象时,最好仔细阅读相关规范文档,以确保正确地使用和释放该对象。