JQuery ajax успешная анонимная функциональная область

Как обновить переменную 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;
}

Ответ 1

Это неправильный подход. Первый 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) {
            // Invoke the callback function, passing the html
            callback(productId, storeId, html);
        }
    });

    // Let the program continue while the html is fetched asynchronously
}

function receivePrice(productId, storeId, html) {
    // Now do something with the returned html
    alert("Product " + productId + " for storeId " + storeId + " received HTML " + html);
}

findPrice(23, 334, receivePrice);

Ответ 2

Короткий ответ, вы не можете, первый A в AJAX означает Asynchronous, что означает, что запрос все еще идет, когда вы попадаете в оператор return.

Вы можете выполнить синхронный (неасинхронный) запрос, но обычно это Bad Thing

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

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
}

Изменить. Sheesh, вы, ребята, быстрее говорите, что я сказал: -)

Ответ 3

Ваша анонимная функция имеет доступ к переменной 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);
});