JQuery AJAX успеха анонимных функций области - PullRequest
38 голосов
/ 22 сентября 2009

Как обновить переменную returnHtml из анонимной функции успеха?

function getPrice(productId, storeId) {
    var returnHtml = '';

    jQuery.ajax({
        url: "/includes/unit.jsp?" + params,
        cache: false,
        dataType: "html",
        success: function(html){
            returnHtml = html;
        }
    });

    return returnHtml;
}

Ответы [ 3 ]

62 голосов
/ 22 сентября 2009

Это неправильный подход. Первый A в AJAX является асинхронным. Эта функция возвращается до возврата вызова AJAX (или, по крайней мере, может). Так что это не проблема масштаба. Это вопрос заказа. Есть только два варианта:

  1. Сделать вызов AJAX синхронным ( не рекомендуется ) с опцией async: false; или
  2. Измените свое мышление. Вместо того, чтобы возвращать HTML из функции, вам нужно передать обратный вызов, который будет вызываться при успешном вызове AJAX.

В качестве примера (2):

function findPrice(productId, storeId, callback) {
    jQuery.ajax({
        url: "/includes/unit.jsp?" + params,
        cache: false,
        dataType: "html",
        success: function(html) {
            callback(productId, storeId, html);
        }
    });
}

function receivePrice(productId, storeId, html) {
    alert("Product " + productId + " for storeId " + storeId + " received HTML " + html);
}

findPrice(23, 334, receive_price);
14 голосов
/ 22 сентября 2009

Короткий ответ, вы не можете, первый A в AJAX означает Асинхронный, что означает, что запрос все еще выполняется, когда вы добираетесь до оператора return.

Вы можете сделать это с синхронным (не асинхронным) запросом, но обычно это Плохая вещь

Что-то вроде следующего: нужно вернуть данные.

function getPrice(productId, storeId) {
  var returnHtml = '';

  jQuery.ajax({
    url: "/includes/unit.jsp?" + params,
    async: false,
    cache: false,
    dataType: "html",
    success: function(html){
      returnHtml = html;
    }
  });

  return returnHtml;
}

НО

Если вам действительно не нужно иметь возможность сразу же использовать возвращаемое значение из теста, вам будет намного лучше, если передать обратный вызов в тест. Что-то вроде

function getPrice(productId, storeId, callback) {
  jQuery.ajax({
    url: "/includes/unit.jsp?" + params,
    async: true,
    cache: false,
    dataType: "html",
    success: function(html){
      callback(html);
    }
  });
}

//the you call it like
getPrice(x,y, function(html) {
    // do something with the html
}

Редактировать Блин, вы, ребята, быстрее говорите то, что я сказал: -)

12 голосов
/ 22 сентября 2009

Ваша анонимная функция там имеет доступ к переменной returnHtml в своей области видимости, и поэтому код на самом деле работает так, как вы ожидаете. То, где вы, вероятно, ошибаетесь, указано в вашем заявлении о возвращении.

Помните, что A в AJAX означает asynchronous, что означает, что это не происходит одновременно. По этой причине строка returnHtml = html на самом деле происходит после , которую вы вызываете return returnHtml;, поэтому returnHtml по-прежнему является пустой строкой.

Трудно сказать, что вы должны сделать, чтобы это работало так, как вы хотите, не видя остальной части вашего кода, но вы могли бы добавить еще один обратный вызов для функции:

function getPrice(productId, storeId, callback) {
    jQuery.ajax({
        url: "/includes/unit.jsp?" + params,
        cache: false,
        dataType: "html",
        success: callback
    });
}

getPrice(5, 1, function(html) {
    alert(html);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...