You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@cordova.apache.org by "Jesse MacFadyen (JIRA)" <ji...@apache.org> on 2014/08/15 00:49:19 UTC
[jira] [Resolved] (CB-4873) XHRHelper is failing with simultaneous
asynchronous requests
[ https://issues.apache.org/jira/browse/CB-4873?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Jesse MacFadyen resolved CB-4873.
---------------------------------
Resolution: Fixed
Fixed with CB-6763
> 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: WP8
> Affects Versions: 3.0.0
> Environment: Any
> Reporter: Jonathan Naguin
> Assignee: Jesse MacFadyen
> Priority: Critical
> Labels: WP8, WP8.1, ajax, asynchronous, multiple, xhrhelper
> Attachments: CordovaWP8_3.6.0-dev1.zip, CordovaWP8_WP8.1_3.4.1.zip
>
>
> 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)