简体   繁体   English

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

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

How can I correctly use jQuery deferreds to delay return of function until async call within function complete + get return value? 如何才能正确使用jQuery延迟来延迟函数返回,直到函数内的异步调用完成+获取返回值?

This is my current code: 这是我目前的代码:

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

I want this to print {"field1":"value1","field2":"value2"} 我想要打印{“field1”:“value1”,“field2”:“value2”}

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

However, the value of result appears to be a jQuery object - so I'm doing something wrong, but what? 但是,结果的值似乎是一个jQuery对象 - 所以我做错了什么,但是什么?

Thanks! 谢谢!


PS Sorry for the newbie question, I am a first time user of deferreds, so I am still grasping the basic concepts. PS对不起新手问题,我是deferreds的第一次使用者,所以我仍然掌握基本概念。

The only way to delay the return of your getFields function would be to set the AJAX async property to false: 延迟返回getFields函数的唯一方法是将AJAX async属性设置为false:

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

But the jQuery documentation notes that this is deprecated from 1.8 onwards (ie it's use is discouraged). 但jQuery文档指出,这是从1.8开始不推荐使用的(即不鼓励使用它)。

Deferreds don't make AJAX synchronous, instead they make it easier to work with callbacks and asynchronous methods. 延迟不会使AJAX同步,相反,它们可以更容易地使用回调和异步方法。

From what I can tell of what you're trying to it might work better to do something like this: 从我所知道的你想要做的事情来看,做这样的事情可能会更好:

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

Then use the promise object like this: 然后像这样使用promise对象:

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

Note that getFields returns a Promise object immediately but you have to wait for the promise to be resolved before you can log out the result. 请注意, getFields立即返回Promise对象,但您必须等待承诺得到解决才能注销结果。

Here's the basic idea of deferreds: you're returned an object, and you can use it to define functions that will be called when the return value comes back. 这是延迟的基本思想:您返回了一个对象,您可以使用它来定义返回值返回时将被调用的函数。 So you could do something like: 所以你可以这样做:

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

Then you can call it and specify a function to be called when the XHR call completes: 然后你可以调用它并指定一个在XHR调用完成时调用的函数:

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

The object is chainable, so you can just do this: 该对象是可链接的,因此您可以这样做:

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

Note that the jqXHR object returned by $.ajax is a Deferred-compatible object, so you can read the documentation at http://api.jquery.com/category/deferred-object/ . 请注意, $.ajax返回的jqXHR对象是与Deferred兼容的对象,因此您可以在http://api.jquery.com/category/deferred-object/上阅读文档。

I'm not sure what you meant by your sample code (since it doesn't actually use the Ajax call) but maybe you meant something like this: 我不确定你的示例代码是什么意思(因为它实际上并没有使用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)); });

This will print your desired value a second after you run it. 这将在您运行它后立即打印您想要的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM