views:

42

answers:

3

I have to request data for a JS-script from a MySQL database (based upon a user-id).

I did not find a simple solution for JavaScript and it was not possible to load the data using ajax, because the database is available under a different domain.

I implemented a workaround using PHP and curl.
Now the JS has to "wait" for the request to finish, but the script is of course running asynchronously and does not wait for the response.
I know that it's not really possible to wait in JS, but it must be possible to return value like this.

I also tried using a return as another callback, but that didn't work of course, because the getter-function will run further anyway.

How can I implement a simple getter, which "waits" and returns the response from the HTTP-request?

Thanks for any other clues. I'm really lost at the moment.
This is a excerpt from the source code:

/**
 * Simple getter which requests external data
 */
function simple_getter() {

    // http request using a php script, because ajax won't work crossdomain
    // this request takes some time. function finished before request is done.

    /* Example */
    var url = "http://example-url.com/get_data.php?uid=1234";
    var response_callback = handle_result_response;

    var value = send_request( url, response_callback );

    value = value.split('*')[0];

    if (value === '' || value == const_pref_none) {
        return false;
    }

    /* 1. returns undefinied, because value is not yet set.
       2. this as a callback makes no sense, because this function
          will run asynchronous anyway. */
    return value;
}

Additional information about the used functions:

/**
 * Callback for the send_request function.
 * basically returns only the responseText (string)
 */
function handle_result_response(req) {
    // do something more, but basically:
    return req.responseText;
}

/**
 * Requests data from a database (different domain) via a PHP script
 */
function send_request( url, response_callback ) {
    var req = createXMLHTTPObject();

    if (!req)
        return;

    var method = (postData) ? "POST" : "GET";

    req.open(method, url, true);
    req.setRequestHeader('User-Agent','XMLHTTP/1.0');

    // More not relevant source code
    // ...

    req.onreadystatechange = function () {
        // More not relevant source code
        // ...

        response_callback(req);
    }

    if (req.readyState == 4)
        return;

    req.send(postData);

}

Not really relevant code, but required for the HTTP-request:

var XMLHttpFactories = [
    function () {return new XMLHttpRequest()},
    function () {return new ActiveXObject("Msxml2.XMLHTTP")},
    function () {return new ActiveXObject("Msxml3.XMLHTTP")},
    function () {return new ActiveXObject("Microsoft.XMLHTTP")}
];


function createXMLHTTPObject() {
    var xmlhttp = false;

    for (var i=0; i<XMLHttpFactories.length; i++) {

        try {
            xmlhttp = XMLHttpFactories[i]();
        } catch (e) {
            continue;
        }

        break;
    }

    return xmlhttp;
}
A: 

I don't see whats wrong with your code in general.

When you make a request, provide a Callback. When a response comes back, which you can easily detect, execute the Callback and pass it the result.

michael
+2  A: 

You really, really shouldn't try to synchronously wait for a network request to complete. The request may never complete, may hang and take a long time, and so on. Since JavaScript is single threaded, and in fact all major browser engines are single threaded, this will cause your entire page to hang while waiting for the request, and in some browsers, may cause the entire browser to hang.

What you should do is replace code like this:

var returned = some_request('http://example.com/query');
do_something_with(returned);

with code like this:

some_request('http://example.com/query', function (returned) {
  do_something_with(returned);
});

That way, you will never cause your page or the browser to hang waiting for the request, and can simply do the work once the response comes in.

Brian Campbell
A: 

This is the way client side apps work.
It is not procedural, but works by events.

  1. You present the screen to the user and wait
  2. The user makes an action
  3. You call the server, set a callback and wait
  4. The response come and you execute the callback and wait for another step 2

Rather than trying to change that, you need to fit with that or it will be a painful experience.

Javascript is not multithreaded. It means a single statement is run at a time. The real asynchronism come from the time the server takes to respond and call the callback. You never know which call will come first and need to build your program with that in mind.

Mic