jQuery deferred:用于延迟函数的返回,直到函数内的异步调用完成+获取返回值

jQuery deferred : use to delay return of function until async call within function complete + get return value

本文关键字:函数 调用 异步 返回值 获取 用于 deferred 延迟 返回 jQuery      更新时间:2023-09-26

如何正确使用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)); 

然而,result的值似乎是一个jQuery对象——所以我做错了什么,但怎么办?

谢谢!


附言:对不起,我是第一次使用延迟,所以我仍然在掌握基本概念。

延迟返回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();
}

然后像这样使用promise对象:

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

请注意,getFields会立即返回一个Promise对象,但您必须等待promise得到解决,然后才能注销结果。

以下是延迟的基本思想:返回一个对象,您可以使用它来定义返回值返回时将调用的函数。所以你可以做一些类似的事情:

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); });

请注意,$.ajax返回的jqXHR对象是一个Deferred兼容对象,因此您可以在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)); });

这将在您运行后一秒钟打印您想要的值。