为什么XMLHttpRequest实例只能发送一个请求?

时间:2014-03-17 10:20:04

标签: javascript ajax asynchronous xmlhttprequest request

我试图从XMLHttpRequest对象的单个实例发送多个请求,如下所示:

GC3D.Application.prototype.setMapTiles = function() {
    var ajaxInstance = new GC3D.Ajax();
    for ( var i = 0, j = 0; i < 10; i++ ) {
        var urlFinal = this.prepareRequestForTileDownload( i, j );
        ajaxInstance.sendRequest({
            id: { i: i, j: j },
            HttpMethod: 'GET',
            UrlEndpoint: urlFinal
        }).then( function( item ) {
                   //...
                });
       }

};

它不起作用,只发送一个请求。但!如果要将源代码更改为下一个:

for ( var i = 0, j = 0; i < 10; i++ ) {
    var ajaxInstance = new GC3D.Ajax();
...

它开始发送许多请求作为for循环迭代的总数,并且一切正常。我更喜欢了解一些功能。就像在我过去的C#开发中一样,我从不在循环中创建一些TCP套接字的新实例,如果我想异步创建它 - 我创建一个带有委托给异步函数的单个实例,如果在C#项目中有类似的情况,比如问题的内容中包含JavaScript代码,因为它不会在for循环中生成新对象,占用的内存更少,而对于体系结构来说,它代表了更干净,更好的解决方案

GC3D.Ajax被定义为下一个原型:

GC3D.Ajax = function() {
    this.httpRequest = undefined;
    this.listExceptions = undefined;
    this.init();
};
GC3D.Ajax.prototype.init = function() {
    this.listExceptions = [];

    if ( window.XMLHttpRequest ) this.httpRequest = new XMLHttpRequest();
    else if ( window.ActiveXObject ) {
        try {
            this.httpRequest = new ActiveXObject( 'Microsoft.XMLHTTP' );
        }
        catch ( exception ) {
            this.listExceptions.push( exception );

            try {
                this.httpRequest = new ActiveXObject( 'Msxml2.XMLHTTP' );
            } 
            catch ( exception ) {
                this.listExceptions.push( exception );

                try {
                    this.httpRequest = new ActiveXObject( 'Microsoft.XMLHTTP' );
                } 
                catch ( exception ) {
                    this.listExceptions.push( exception );
                }
            }
        }
    }

    if ( !this.httpRequest ) {
        console.error( 'Can\'t create a HTTP Request instance for AJAX! Possible problems:' );
        console.error( this.listExceptions );
    }
};
GC3D.Ajax.prototype.sendRequest = function( properties ) {
    var defer = new GC3D.Defer();
    if ( this.httpRequest !== undefined ) {
        this.httpRequest.onreadystatechange = function() {
            if ( this.httpRequest.readyState === 4 && this.httpRequest.status === 200 ) {
                var objectOutput = {};
                objectOutput.id = properties.id;
                objectOutput.content = this.httpRequest.responseText;
                defer.resolve( objectOutput );
            }
            else {
                var message = 'There was a problem with the request in GC3D.Ajax.';
                defer.reject( message );
            }
        }.bind( this );
        this.httpRequest.open( properties.HttpMethod, properties.UrlEndpoint );
        this.httpRequest.send();
    }
    else console.error( 'HTTP Request instance isn\'t defined!' );
    return defer.promise;
};
GC3D.Ajax.prototype.get = function() {
    return this.httpRequest;
};

1 个答案:

答案 0 :(得分:0)

XMLHttpRequest API的定义非常明确,对此行为毫无疑问。

open()方法的定义,步骤13,声明该方法应该:

Terminate the request. 

http://www.w3.org/TR/XMLHttpRequest/#the-open()-method

在浏览器中打开一个调试器并查看网络流量后发现,实际上有几个请求是异步发送的,每个请求都会被下一个请求取消。

在这种情况下,open()方法在sendRequest ajaxInstance方法的同一个XMLHttpRequest实例上重复调用。