[ https://issues.apache.org/jira/browse/CB-4873?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Jesse MacFadyen reopened CB-4873: --------------------------------- > XHRHelper is failing with simultaneous asynchronous requests > ------------------------------------------------------------ > > Key: CB-4873 > URL: https://issues.apache.org/jira/browse/CB-4873 > Project: Apache Cordova > Issue Type: Bug > Components: WP7, WP8 > Affects Versions: 3.0.0 > Environment: Any > Reporter: Jonathan Naguin > Assignee: Jesse MacFadyen > Priority: Critical > Labels: WP8, WP8.1, ajax, asynchronous, multiple, xhrhelper > > XHRHelper is failing in processing mutiple simultaneous asynchronous AJAX > requests. I am using the latest code from > https://github.com/apache/cordova-wp8/blob/master/wp8/template/cordovalib/XHRHelper.cs > The problem is related with {{_onXHRLocalCallback}} which is save into the > {{window}} object as a unique function. When, for example, two Ajax requests > are evaluated at same time, the last {{funk}} function overrides the first > {{_onXHRLocalCallback}} without receive the data from the C# code to that > particular request. > To demostrate this I put {{console.log("XHR: " + resolvedUrl);}} inside > {{__onXHRLocalCallback}} and > {{System.Diagnostics.Debug.WriteLine("HandleCommand: " + url);}} in > {{HandleCommand}} method (my code uses *Require JS* to load this resources). > The output is this: > {code} > HandleCommand: x-wmapp0:www/src/modules/home/HomeView.html > HandleCommand: x-wmapp0:www/src/modules/orders/OrdersView.html > XHR: x-wmapp0:www/src/modules/orders/OrdersView.html > XHR: x-wmapp0:www/src/modules/orders/OrdersView.html > XHR: HandleCommand: x-wmapp0:www/src/modules/order/OrderDetailView.html > XHR: x-wmapp0:www/src/modules/order/OrderDetailView.html > {code} > As you can see, one request is missing: "HomeView.html". > h6. NOTES > - If I set {{false}} the {{this.isAsync}} variable it works (this way it is > executed without using setTimeout). > - If I put a console.log before launch {{funk}} it works. > - It works on the simulator, but it fails on a real device. > h6. Possible solution > In conclusion, I assumed that it's a timing problem. To resolve it I decided > to save a onXHRLocalCallback function per each request: > {code} > var funk = function () { > if (! window.__onXHRLocalCallback){ > window.__onXHRLocalCallback = {}; //Object to store the functions > } > > window.__onXHRLocalCallback[resolvedUrl] = function (responseCode, > responseText) { > alias.status = responseCode; > if (responseCode == '200') { > alias.responseText = responseText; > } > else { > alias.onerror && alias.onerror(responseCode); > } > alias.changeReadyState(XHRShim.DONE); > delete window.__onXHRLocalCallback[resolvedUrl]; //Delete the function > } > alias.changeReadyState(XHRShim.LOADING); > window.external.Notify('XHRLOCAL/' + resolvedUrl); > } > {code} > So I had to change in {{HandleCommand}} method the way of invoking this > callback. I decided to create a helper function to be called in each case: > {code} > /// <summary> > /// Invoke a XHR callback > /// </summary> > /// <param name="url">The URL of the request</param> > /// <param name="code">The response code</param> > /// <param name="text">The response text</param> > private void InvokeCallback(string url, int code, string text) > { > string args = string.Format("('{0}', {1}, {2});", code, > WPCordovaClassLib.Cordova.JSON.JsonHelper.Serialize(text), > WPCordovaClassLib.Cordova.JSON.JsonHelper.Serialize(url)); > string callback = @"(function(code, text, url){ > try { > window.__onXHRLocalCallback[ url ].call(null, code, text); > } > catch(e) { > console.log('Error calling method from XHRHelper :: ' + e); > } > })" + args; > Browser.InvokeScript("eval", new string[] { callback }); > } > {code} > To be called as {{InvokeCallback(url, 200, text);}} or {{InvokeCallback(url, > 404, null);}} > Thanks. -- This message was sent by Atlassian JIRA (v6.2#6252)