Search code examples
javascriptrestdelphidelphi-xe7datasnap

javascript calling DataSnap REST makes browser unresponsive


I use Delphi XE7. When my Javascript calls my server function that need around 800ms to read sensor and return data, The browser is unresponsive from the moment I click the button to invoke the Javascript until it finally response returns. I'm using the default Javascript generated by the proxy var serverMethods().getChannel(i); to call into my server function.

Javascript call look like this:

var s = serverMethods().getChannel(i);
      serial[i].$sensorlValue.text(s.result.fields.sensorString);
      serial[i].$sensorlRealValue.text(s.result.fields.sensor);
      serial[i].$sensorStatus.text(s.result.fields.sensorStatus+' '+s.result.fields.name);
      serial[i].$sensorError.text(s.result.fields.sensorError);
      serial[i].$AVString.text(s.result.fields.AVString);
      serial[i].$AVError.text(s.result.fields.AVError);

So by default example there are no Javascript callbacks or promise, so embaracaderom manage somehow to block Javascript from executing until response is back and variable a receive values?

I think about try using jQuery Ajax call on URL, but is there any other solution?

Because serverMethods are generated from proxy but for $ajax I need to manually set each of them. Or maybe I do something wrong here and serverMethods can be used without blocking ?

Thanks.


Solution

  • I found the solution to this problem after researching execution path in ServerFunctionExecutor.js that is called on serverMethods().SOMEAPIFUNCTION() 1. Help and documentation are 0, and google + XE7 questions are 0. So if someone from embaracadero read this PLS MAKE DECENT DOCUMENTATION.

    ServerFunctionExecutor.js had on line 263

       //async is only true if there is a callback that can be notified on completion
    var useCallback = (callback != null);
    request.open(requestType, url, useCallback);
    
    if (useCallback)
    {
      request.onreadystatechange = function() {
        if (request.readyState == 4)
        {
          //the callback will be notified the execution finished even if there is no expected result
          JSONResult = hasResult ? parseHTTPResponse(request) : null;
          callback(JSONResult, request.status, owner);
        }
      };
    }
    

    So it is posible and NOT DOCUMENTED to use callback for unblocking GUI. Use it as:

    serverMethods().SOMEAPIFUNCTION(par1,par2,.... callback)
    

    If you have Server method defined in delphi code with for example 3 parameters in js 4th parameter is callback:

    For this example code now look like this:

     serverMethods().getChannel(i,function(a,b,c){
                serial.$sensorlValue.text(a.result[0].fields.sensorString);
                serial.$sensorlRealValue.text(a.result[0].fields.sensor);
                serial.$sensorStatus.text(a.result[0].fields.sensorStatus+' '+s.result.fields.name);
                serial[i].$sensorError.text(a.result[0].fields.sensorError);
                serial[i].$AVString.text(a.result[0].fields.AVString);
                serial[i].$AVError.text(a.result[0].fields.AVError);
              });
    

    a is JSON reponse
    b is Request status as number 200 or somethin else
    c is owner usuali undefined