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

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

Как я могу правильно использовать отложенные jQuery для задержки возврата функции до тех пор, пока асинхронный вызов внутри функции не завершится + получить возвращаемое значение?

Это мой текущий код:

function getFields(page)
{
  var dff = $.Deferred();
  result = {};
  $.ajax( //the async call
    {
      url: page,
      success:
        function (data)
        {
          //work out values for field1 & field 2 from data here
          result = 
          {
            'field1' : field1,
            'field2' : field2
          };
        },
      complete:
        function()
        {
          dff.resolve(result); //my attempt to return the result
        }
    }
  );
  return dff.promise();
}

Я хочу, чтобы это напечатало { "field1": "value1", "field2": "value2" }

var result = getFields('http://something');
console.log(JSON.stringify(result)); 

Однако значение результата выглядит как объект jQuery, поэтому я делаю что-то неправильно, но что?

Спасибо!


P.S. Извините за вопрос о новичке, я первый пользователь отложенных, поэтому я все еще понимаю основные понятия.

4b9b3361

Ответ 1

Единственный способ отсрочить возврат вашей функции getFields - это установить для свойства AJAX async значение false:

   var ajaxPromise = $.ajax(
    {
      url: page,
      async: false  // make the call synchronous
    }
  );

Но в документации jQuery отмечается, что это устарело от 1,8 и более (то есть использование не рекомендуется).

Отсрочки не делают AJAX синхронным, вместо этого упрощают работу с обратными вызовами и асинхронными методами.

Из того, что я могу сказать о том, что вы пытаетесь сделать, может работать лучше, чтобы сделать что-то вроде этого:

function getFields(page)
{
  var ajaxPromise = $.ajax( //the async call
    {
      url: page
    }
  );

  var dff = $.Deferred();
  ajaxPromise.then(function(data){

    // Possibly access the loaded data in this function.
    var result = {
      'field1' : field1,
      'field2' : field2
    };

    // Notify listeners that the AJAX call completed successfully.
    dff.resolve(result);

  }, function(){
    // Something went wrong - notify listeners:
    dff.reject(/* possibly pass information about the error */);
  });

  return dff.promise();
}

Затем используйте объект обещания следующим образом:

var fieldPromise = getFields('http://something');
fieldPromise.done(function(result){
  console.log(JSON.stringify(result)); 
});

Обратите внимание, что getFields немедленно возвращает объект Promise, но вы должны дождаться, пока обещание будет устранено, прежде чем вы сможете выйти из него.

Ответ 2

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

function getFields(page)
{
    return $.ajax(page);
}

Затем вы можете вызвать его и указать функцию, вызываемую при завершении вызова XHR:

var jqXHR = getFields("/path/to/call");
jqXHR.done(function (data) { alert(JSON.stringify(data); });

Объект привязан, поэтому вы можете просто сделать это:

getFields("/path/to/call")
    .done(function (data) { alert(JSON.stringify(data); });

Обратите внимание, что объект jqXHR, возвращаемый $.ajax, является объектом, совместимым с отсрочкой, поэтому вы можете прочитать документацию в http://api.jquery.com/category/deferred-object/.

Я не уверен, что вы имели в виду под своим примером кода (поскольку на самом деле он не использует вызов Ajax), но, возможно, вы имели в виду что-то вроде этого:

function getFields()
{
    var df = $.Deferred();
    window.setTimeout(function () {
        df.resolve({field1: "value1", field2: "value2"});
    }, 1000);
    return df.promise();
}

getFields().done(function (data) { console.log(JSON.stringify(data)); });

После того, как вы запустите его, вы получите нужное значение в секундах.