JavaScript 异步返回值/jQuery 赋值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7779697/
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
JavaScript asynchronous return value / assignment with jQuery
提问by patrick
I have the following jQuery Function. I'm trying to return the GUID value shown here in the alert();
The alert works fine and the value is populated, however I can't seem to assign it to a variable and return its value.
我有以下 jQuery 函数。我试图返回此处显示的 GUID 值alert();
警报工作正常并且值已填充,但是我似乎无法将其分配给变量并返回其值。
Ultimately I need to access the GUID value in other functions, etc. Everything I've tried only displays as undefined
.
最终我需要访问其他函数中的 GUID 值等。我尝试过的所有内容都只显示为undefined
.
I'd like to do something like this:
我想做这样的事情:
function trackPage(){
var elqTracker = new jQuery.elq(459);
elqTracker.pageTrack({
success: function() {
elqTracker.getGUID(function(guid) {
alert(guid);
var returnValue = guid;
});
}
});
return returnValue;
}
var someGuid = trackPage();
回答by gnarf
So, this question has been asked a million times over, and I'm sure that everyone (myself included) tried this once.
所以,这个问题已经被问了一百万次了,我相信每个人(包括我自己)都试过一次。
It is just the nature of an asynchronous call, you can't use their results as a return
value. Thats why they have you passing in a function that gets the result of the call, they can't return
it either! Also notice that the elqTracker.pageTrack()
function call returns IMMEDIATELY, therefore your returnValue
is simply undefined
.
这只是异步调用的性质,您不能将它们的结果用作return
值。这就是为什么他们让你传入一个获取调用结果的函数,他们也不能return
!另请注意,elqTracker.pageTrack()
函数调用立即返回,因此您returnValue
只是undefined
.
Most people (see dfsq's answer) solve this problem by introducing a callback function as a paramater. This method is tried, and true – however jQuery has $.Deferred
. This allows you to make your own asynchronous logic return a promise
which you can then attach any number of callbacks to:
大多数人(参见 dfsq 的回答)通过引入回调函数作为参数来解决这个问题。这种方法已经尝试过,并且是正确的——但是 jQuery 有$.Deferred
. 这允许您让自己的异步逻辑返回 a promise
,然后您可以将任意数量的回调附加到:
function trackPage(){
var elqTracker = new jQuery.elq( 459 ),
dfd = $.Deferred();
elqTracker.pageTrack({
success: function() {
elqTracker.getGUID(function( guid ) {
dfd.resolve( guid );
});
}
});
return dfd.promise();
}
// example use:
trackPage().done(function( guid ) {
alert( "Got GUID:" + guid );
});
Notice now that your trackPage()
returns an object that you can attach callbacks to? You don't have to attach them immediately either.
现在注意到您trackPage()
返回了一个可以附加回调的对象吗?您也不必立即附加它们。
var pageHit = trackPage().done(function( guid ) {
alert( "Page Hit GUID:" +guid );
});
$("button").click(function() {
pageHit.done( function( guid ) {
alert( "Clicked on Page GUID:" + guid );
});
});
Also, the jQuery AJAX module always returns promises as well, so the interface for all your AJAX stuff should be very similar if you make your own logic return promises.
此外,jQuery AJAX 模块也总是返回承诺,因此如果您使自己的逻辑返回承诺,则所有 AJAX 内容的界面应该非常相似。
As a side note: I'd like to point out that your var returnValue
was in the wrong "scope" anyway. It needed to be declared in the outer scope of the trackPage
function. Even with this fix, the concept still doesn't work.
附带说明:var returnValue
无论如何,我想指出您的“范围”是错误的。它需要在trackPage
函数的外部范围内声明。即使有了这个修复,这个概念仍然不起作用。
回答by dfsq
Since you have asynchronous call the way you are trying to write code is not going to work (because by the moment of return returnValue;
in the trackCode return value is not yet defined). Instead you should pass callback into trackPage:
由于您有异步调用,因此您尝试编写代码的方式将不起作用(因为此时return returnValue;
trackCode 返回值尚未定义)。相反,您应该将回调传递给 trackPage:
function trackPage(callback) {
var elqTracker = new jQuery.elq(459);
elqTracker.pageTrack({
success: function() {
elqTracker.getGUID(function(guid) {
alert(guid);
// Instead of this: var returnValue = guid;
// You should use your callback function
callback(guid);
});
}
});
return returnValue;
}
trackCode(function(guid) {
// perform some actions with guid
});