尝试将现有的同步XmlHttpRequest对象转换为异步以跟上当前的时尚

时间:2016-09-25 08:31:12

标签: javascript asynchronous xmlhttprequest

Soo,我一直对Chrome的注意事项感到不安,因为我们已经决定将XmlHttpRequest调用同步放弃,并且我决定尝试将我的用例转换为跟上这个时尚。

在这种情况下,我有一个〜9岁的JS对象,它已被用作使用同步XHR调用在服务器和基于Web的应用程序之间传输数据的中心(和示例)方法。我已经创建了一个简化版本来发布(通过大量的理智,安全和语法检查):

function GlobalData()
{
    this.protocol = "https://";
    this.adminPHP = "DataMgmt.php";
    this.ajax = false;
    this.sessionId = "123456789AB";
    this.validSession = true;
    this.baseLocation = "http://www.example.com/";
    this.loadResult = null;

    this.AjaxPrep = function()
    {
        this.ajax = false;
        if (window.XMLHttpRequest) {
            try { this.ajax = new XMLHttpRequest(); } catch(e) { this.ajax = false; } }
    }

    this.FetchData = function (strUrl)
    {
        if ((typeof strURL=='string') && (strURL.length > 0))
        {
            if (this.ajax === false)
            {
                this.AjaxPrep();
                if (this.ajax === false) { alert('Unable to initialise AJAX!'); return ""; }
            }

            strURL = strURL.replace("http://",this.protocol); // We'll only ask for data from secure (encrypted-channel) locations...
            if (strURL.indexOf(this.protocol) < 0) strURL = this.protocol + this.adminPHP + strURL;
            strURL += ((strURL.indexOf('?')>= 0) ? '&' : '?') + 'dynamicdata=' + Math.floor(Math.random() * this.sessionId);
            if (this.validSession) strURL += "&sessionId=" + this.sessionId;
            this.ajax.open("GET", strURL, false);
            this.ajax.send();
            if (this.ajax.status==200) strResult = this.ajax.responseText;
            else alert("There was an error attempting to communicate with the server!\r\n\r\n(" + this.ajax.status + ") " + strURL);
            if (strResult == "result = \"No valid Session information was provided.\";")
            {
                alert('Your session is no longer valid!');
                window.location.href = this.baseLocation;
            }
        }
        else console.log('Invalid data was passed to the Global.FetchData() function. [Ajax.obj.js line 62]');
        return strResult;
    }

    this.LoadData = function(strURL)
    {
        var s = this.FetchData(strURL);
        if ((s.length>0) && (s.indexOf('unction adminPHP()')>0))
        {
            try
            {
                s += "\r\nGlobal.loadResult = new adminPHP();";
                eval(s);
                if ((typeof Global.loadResult=='object') && (typeof Global.loadResult.get=='function')) return Global.loadResult;
            } catch(e) { Global.Log("[AjaxObj.js] Error on Line 112: " + e.message); }
        }
        if ( (typeof s=='string') && (s.trim().length<4) ) 
            s = new (function() { this.rowCount = function() { return -1; }; this.success = false; });
        return s;
    }
}
var Global = new GlobalData();

这个“全局”对象在成千上万行代码中被引用数百次,如下所示:

// Sample data request...
var myData = Global.LoadData("?fn=fetchCustomerData&sortByFields=lastName,firstName&sortOrder=asc");
if ((myData.success && (myData.rowCount()>0)) 
{ 
    // Do Stuff...
    // (typically build and populate a form, input control 
    // or table with the data)
}

服务器端API旨在处理遇到的所有无数种类的请求,并且在每种情况下,执行返回调用函数所寻求的数据所需的任何魔法。下面是对查询的纯文本响应示例(API会自动将任何SQL查询的结果转换为此格式;调整字段和数据以反映动态检索的数据;下面的示例数据已经过匿名):

/* Sample return result (plain text) from server:
function adminPHP()
{
    var base = new DataInterchangeBase();
    this.success = true;
    this.colName = function(idNo) { return base.colName(idNo); }
    this.addRow = function(arrRow) { base.addRow(arrRow); }
    this.get = function(cellId,rowId) { return base.getByAbsPos(cellId,rowId); }
    this.getById = function(cellId,rowId) { return base.getByIdVal(cellId,rowId); }
    this.colExists = function(colName) { return ((typeof colName=='string') && (colName.length>0)) ? base.findCellId(colName) : -1; }
    base.addCols( [ 'id','email','firstName','lastName','namePrefix','nameSuffix','phoneNbr','companyName' ] );
    this.id = function(rowId) { return base.getByAbsPos(0,rowId); }
    this.email = function(rowId) { return base.getByAbsPos(1,rowId); }
    this.firstName = function(rowId) { return base.getByAbsPos(2,rowId); }
    this.lastName = function(rowId) { return base.getByAbsPos(3,rowId); }
    this.longName = function(rowId) { return base.getByAbsPos(5,rowId); }
    this.namePrefix = function(rowId) { return base.getByAbsPos(6,rowId); }
    this.nameSuffix = function(rowId) { return base.getByAbsPos(7,rowId); }
    this.companyName = function(rowId) { return base.getByAbsPos(13,rowId); }
    base.addRow( [ "2","biff@nexuscons.com","biff","broccoli","Mr.","PhD","5557891234","Nexus Consulting",null ] );
    base.addRow( [ "15","happy@daysrhere.uk","joseph","chromebottom","Mr.","","5554323456","Retirement Planning Co.",null ] );
    base.addRow( [ "51","michael@sunrisetravel.com","mike","dolittle","Mr.","",""5552461357","SunRise Travel",null ] );
    base.addRow( [ "54","info@lumoxchemical.au","patricia","foxtrot","Mrs,","","5559876543","Lumox Chem Supplies",null ] );
    this.query = function() { return " SELECT `u`.* FROM `users` AS `u` WHERE (`deleted`=0) ORDER BY `u`.`lastName` ASC, `u`.`firstName` LIMIT 4"; }
    this.url = function() { return "https://www.example.com/DataMgmt.php?fn=fetchCustomerData&sortByFields=lastName,firstName&sortOrder=asc&dynamicdata=13647037920&sessionId=123456789AB\"; }
    this.rowCount = function() { return base.rows.length; }
    this.colCount = function() { return base.cols.length; }
    this.getBase = function() { return base; }
}
*/

在几乎每个调用此代码的实例中,调用函数在以预期的对象形式接收来自请求的所有数据之前无法执行其工作。

所以,我已经阅读了一些关于执行异步调用的内容,以及调用在数据准备就绪时通知的回调函数的必要性,但是我找不到找到方法将结果数据返回到正在等待它的原始(调用)函数,而不必访问这些数百个实例中的每一个并在每个实例中进行重大更改(即更改调用代码以期望回调函数作为结果而不是预期的数据并采取相应的行动;时间100的实例......)

Sooo,非常感谢任何关于如何进行的指导,帮助或建议!

0 个答案:

没有答案