Как сделать функцию, которая возвращает значение своей внутренней функции? - PullRequest
1 голос
/ 19 декабря 2011

Это, вероятно, очевидно для вас, но я не могу понять это.

Мне нужно сделать функцию, которая возвращает значение своей внутренней функции.Другими словами, у меня есть функция get_users(), которая должна возвращать объект JSON.Этот объект JSON получен с помощью $.post (встроенный jQuery).

function get_users() {    
    return
        $.post(
            url_base + 'travel/trip/get_users/' + trip_id,
            function(response) {    
                return response;    
            },
            'json'
        );    
}

(выше я пытался сделать это, но он вернул undefined - какой сюрприз)

Из-за переменной области, я не могу просто сделать переменную во внутренней функции, потому что она не будет видна в основной функции.Я тоже не хочу использовать глобальные переменные.Ищете лучшее решение!

Спасибо за любой совет!

Ответы [ 3 ]

5 голосов
/ 19 декабря 2011

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

Так вот правильный путь:

function get_users() {
    $.post(
        url_base + 'travel/trip/get_users/' + trip_id, 
        function(response) {
            // instead of trying to return anything here
            // simply do something with the response
            // Depending on what the server sent you there
            // will be different ways.

            // Here you could also call some other custom function
            // and pass it the response
        }
        'json'
    );
}
3 голосов
/ 19 декабря 2011

Вы не можете возвращать значения из вызовов ajax. (Без установки асинхронного false, но это не будет ajax)

К тому времени, когда вы нажмете внутренний возврат, внешняя функция уже завершена

Вам потребуется обратный вызов для обработки пользователей.

get_users(function(response) { // this anonymous function is passed in as a parameter
    // do something with the response
});

function get_users(callback) {
    $.post(
        url_base + 'travel/trip/get_users/' + trip_id,
        function(response) {
            // call the passed in function and pass in the response as a parameter
            callback(response);     
        },
        json'
    );
}
2 голосов
/ 19 декабря 2011

Вам нужен учебник о том, как работают асинхронные вызовы ajax.

Когда вы звоните $.post(), он запускает сетевой вызов, чтобы выполнить сообщение, сразу же возвращается из вызова $.post() и продолжает выполнение остальных.вашего JavaScriptОн даже сразу выйдет из вашей функции get_users().

Но вызов ajax еще не сделан - он все еще выполняется.Через некоторое время вызов ajax завершится, и когда это произойдет, будет вызван обработчик успеха для вызова ajax, который вы определили как function(response) {...}.Только тогда, позднее, будет известно значение ответа от вызова ajax.

Это то, что означает асинхронный ajax.Вы не можете написать вызов типа get_users () и ожидать, что он получит пользователей и вернется с ними.Вместо этого вы должны использовать функции обратного вызова, которые будут вызваны через некоторое время (когда завершится ajax), и тогда вы сможете продолжить путь своего кода.Да, это неудобно, но это то, как все работает в javascript с асинхронными вызовами ajax.Преимущество асинхронных вызовов ajax заключается в том, что браузер и другой код javascript могут полностью работать, пока идет вызов ajax.Стоимость асинхронных вызовов ajax заключается в том, что их кодирование является более сложным.

У вас есть несколько вариантов решения этой проблемы.Во-первых, вы можете сделать свой вызов get_users (), а затем просто продолжить последовательность программирования, которую вы хотите выполнить во внутреннем обратном вызове внутри get_users(), поскольку это единственное место, где известен ответ (фактические пользователи).Если вы используете get_users() только в одном месте своего кода, тогда это может работать нормально.Это выглядело бы так:

function get_users() {
    $.post(
        url_base + 'travel/trip/get_users/' + trip_id,
        function(response) {

            // process the user list here and continue whatever other code you
            // need that deals with the user list
        },
        'json'
    );
}

Если вам нужно использовать get_users() в нескольких разных местах для разных целей, то вы можете изменить его так, чтобы он принимал сам обратный вызов и позволял после звонка просто вызвать этот обратный вызов.когда вызов Ajax сделан.Затем вы завершили бы обработку ответа в этой функции обратного вызова:

function get_users(callback) {
    $.post(
        url_base + 'travel/trip/get_users/' + trip_id,
        callback,
        'json'
    );
}

В этом втором варианте вы можете вызвать get_users() следующим образом:

get_users(function(response) {
    // process the user list here and continue whatever other code you
    // need that deals with the user list
});

Есть еще более продвинутыеопции доступны с использованием отложенного объекта jQuery .

...