Я должен запросить данные для JS-скрипта из базы данных MySQL (на основе идентификатора пользователя).

Я не нашел простого решения для JavaScript, и было невозможно загрузить данные с помощью ajax, потому что база данных доступна в другом домене.

Я реализовал обходной путь, используя PHP и curl.
Теперь JS должен «дождаться» завершения запроса, но, конечно, скрипт работает асинхронно и не ожидает ответа.
Я знаю, что на самом деле нельзя ждать в JS, но должно быть возможно возвращать значение, подобное этому.

Я также попытался использовать return в качестве другого обратного вызова, но это, конечно, не сработало, потому что функция getter будет работать в любом случае дальше.

Как реализовать простой метод получения, который «ждет» и возвращает ответ от HTTP-запроса?

Спасибо за любые другие подсказки. Я действительно потерян в данный момент.
Это выдержка из исходного кода:

/**
 * 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;
}

Дополнительная информация об используемых функциях:

/**
 * 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);

}

Не очень актуальный код, но обязательный для HTTP-запроса:

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;
}
2
Smamatti 9 Сен 2010 в 20:15

3 ответа

Лучший ответ

Вы действительно, действительно, не должны пытаться синхронно ждать завершения сетевого запроса. Запрос может никогда не исполниться, может зависнуть и занять много времени, и так далее. Поскольку JavaScript является однопоточным, и на самом деле все основные механизмы браузера являются однопоточными, это приведет к зависанию всей страницы во время ожидания запроса, а в некоторых браузерах может привести к зависанию всего браузера.

Что вы должны сделать, это заменить код следующим образом:

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

С таким кодом:

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

Таким образом, вы никогда не заставите свою страницу или браузер зависать в ожидании запроса, и можете просто выполнить работу, как только ответ придет.

3
Brian Campbell 9 Сен 2010 в 16:24

Так работают клиентские приложения.
Это не процедурный процесс, а работа по событиям.

  1. Вы представляете экран пользователю и ждете
  2. Пользователь совершает действие
  3. Вы звоните на сервер, устанавливаете обратный вызов и ждете
  4. Ответ приходит, и вы выполняете обратный вызов и ждете другого шага 2

Вместо того, чтобы пытаться изменить это, вам нужно соответствовать этому, или это будет болезненный опыт.

Javascript не является многопоточным. Это означает, что один оператор выполняется одновременно. Настоящий асинхронизм возникает из-за времени, которое требуется серверу, чтобы ответить и вызвать обратный вызов. Вы никогда не знаете, какой вызов будет первым, и вам нужно создать свою программу с учетом этого.

0
Mic 9 Сен 2010 в 17:14

Я не вижу, что не так с вашим кодом в целом.

Когда вы делаете запрос, предоставьте обратный звонок. Когда ответ возвращается, который вы можете легко обнаружить, выполните Callback и передайте ему результат.

0
donohoe 9 Сен 2010 в 16:19