Javascript 重用XMLHttpRequest对象还是创建一个新对象?

Javascript 重用XMLHttpRequest对象还是创建一个新对象?,javascript,ajax,xmlhttprequest,Javascript,Ajax,Xmlhttprequest,我搜索了stackoverflow,但得到了相互矛盾的答案: 此外,w3schools.com上还有一条建议: 如果您的网站上有多个AJAX任务,您应该创建 一个用于创建XMLHttpRequest对象的标准函数,并调用 这适用于每个AJAX任务 为什么会有这样的建议?相反,我在页面上使用了一个全局XMLHttpRequest对象来处理所有Ajax任务。对于正在生成的每个XHR,最好使用不同的对象。即使有办法,也要避免!为每个请求创建新对象没有问题。如果您担心内存泄漏或诸如此类的问题,请不要

我搜索了stackoverflow,但得到了相互矛盾的答案:

此外,w3schools.com上还有一条建议:

如果您的网站上有多个AJAX任务,您应该创建 一个用于创建XMLHttpRequest对象的标准函数,并调用 这适用于每个AJAX任务


为什么会有这样的建议?相反,我在页面上使用了一个全局XMLHttpRequest对象来处理所有Ajax任务。

对于正在生成的每个XHR,最好使用不同的对象。即使有办法,也要避免!为每个请求创建新对象没有问题。如果您担心内存泄漏或诸如此类的问题,请不要担心,它们都经过了正确的GC`ed


如果您的网站上有多个AJAX任务,那么应该创建一个标准函数来创建XMLHttpRequest对象,并为每个AJAX任务调用该函数

实际上,这意味着您有一个函数,该函数创建一个新对象,并在每次调用它时返回它。它有点像:

function newXHR(){
    return a new instance of XHR();
}
function createXHR() {
    try {
        return new XMLHttpRequest();
    } catch (e) {
        try {
            return new ActiveXObject("Microsoft.XMLHTTP");
        } catch (e) {
            return new ActiveXObject("Msxml2.XMLHTTP");
        }
    }
}
var xhr = createXHR();
xhr.open('get', '/test', true);
xhr.send();

你误解了学校的建议。我将重点介绍相关部分:

如果您的网站上有多个AJAX任务,您应该创建一个标准函数来创建XMLHttpRequest对象,并为每个AJAX任务调用该函数

它说您使用一个AJAX函数来获取请求。此函数将处理IE和其他浏览器之间的不一致<标准兼容浏览器中的code>XMLHttpRequest,IE中的
ActiveXObject

我建议使用多个XHR对象。使用一个全局xhr对象,应用程序在给定时间只能处理一个请求。它也容易出错(例如)

学校的意思是:

function newXHR(){
    return a new instance of XHR();
}
function createXHR() {
    try {
        return new XMLHttpRequest();
    } catch (e) {
        try {
            return new ActiveXObject("Microsoft.XMLHTTP");
        } catch (e) {
            return new ActiveXObject("Msxml2.XMLHTTP");
        }
    }
}
var xhr = createXHR();
xhr.open('get', '/test', true);
xhr.send();

尽管最好创建一个处理请求的函数,例如。

但您强调的建议是,您应该有一个处理AJAX的函数,而不是一个XMLHTTPRequest对象

我会对每个问题使用不同的答案

反对这一点的常见论点涉及设置XHR所涉及的管理费用。然而,在任何按照预期使用AJAX的网站上(即,不作为web套接字的劳动替代品),这几乎可以忽略不计,而且,在任何情况下,重复使用XHR也会带来同样的开销。您仍然需要打开连接、启动连接、连接侦听器等

浏览器在一个给定的时间内允许多少个连接网关,因此由浏览器来控制XHR可以做什么。换句话说,您不必担心管理这方面

最后,如果XHR是可删除的(对象的属性而不是变量),那么在使用XHR之后,没有什么可以阻止您手动删除它们。

来自MDN Web文档:

如果全局使用httpRequest变量,则竞争函数 调用makeRequest()可能会相互覆盖,导致竞争 条件将httpRequest变量声明为闭包的局部变量 包含AJAX函数可以避免这种情况


来源:

我正在使用这样的模式

var xhrSendBuffer = new Object();
function sendData(url, model) {
    if (!xhrSendBuffer[url]) {
        let xhr = new XMLHttpRequest();
        xhr.onloadend = xhrDone;
        xhr.error=xhrError;
        xhr.onabort = xhrAbborted;
        xhr.open('POST', url, true);
        xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
        xhrSendBuffer[url] = xhr;
    }

    xhrSendBuffer[url].send(JSON.stringify(model));
}

function xhrDone(e) {
    console.log(e);
}
function xhrError(e) {
    console.error(e);
}
function xhrAbborted(e) {
console.warn(e);
}

如果因为向同一url发送多个请求而在自己的站点上生成DOS,那么在发送下一个请求之前,我可以使用xhr.readyState查看它有多忙,但是我还没有遇到这个问题

我认为他非常理解这项建议,除非他从那时起编辑了他的问题。引用:“我使用的是一个全局XMLHttpRequest对象”——与建议相反,他显然理解为不是一个全局对象,而是多个实例。