javascript jQuery延迟:用于延迟函数的返回,直到函数内的异步调用完成+获取返回值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11444639/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
jQuery deferred : use to delay return of function until async call within function complete + get return value
提问by bguiz
How can I correctly use jQuery deferreds to delay return of function until async call within function complete + get return value?
如何正确使用 jQuery deferreds 延迟函数的返回,直到函数内的异步调用完成 + 获取返回值?
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!
谢谢!
P.S. Sorry for the newbie question, I am a first time user of deferreds, so I am still grasping the basic concepts.
PS抱歉新手问题,我是deferreds的第一次用户,所以我还在掌握基本概念。
采纳答案by Sly_cardinal
The only way to delay the return of your getFields
function would be to set the AJAX async
property to false:
延迟getFields
函数返回的唯一方法是将 AJAXasync
属性设置为 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 (i.e. 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.
Deferred 不会使 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
对象,但您必须等待 promise 得到解决,然后才能注销结果。
回答by Anthony Mills
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/.
请注意,由 返回的 jqXHR 对象$.ajax
是一个与 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.
这将在您运行后一秒钟打印您想要的值。