使用jQuery进行JavaScript异步返回值/赋值

JavaScript asynchronous return value / assignment with jQuery

本问题已经有最佳答案,请猛点这里访问。

我有以下jquery函数。我试图返回EDOCX1中显示的guid值(0)。警报工作正常,并且值已填充,但是我似乎无法将其分配给变量并返回其值。

最后,我需要访问其他函数中的guid值,等等。我尝试过的所有内容都只显示为undefined

我想这样做:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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();


所以,这个问题被问了无数次,我相信每个人(包括我自己)都试过一次。

这只是异步调用的性质,不能将它们的结果用作return值。这就是为什么他们让你传入一个函数来获得调用的结果,他们也不能执行ecx1(1)!还要注意,elqTracker.pageTrack()函数调用会立即返回,因此您的returnValue只是undefined而已。

大多数人(请参阅dfsq的答案)通过引入回调函数作为参数来解决这个问题。尝试使用此方法,但jquery使用的是$.Deferred。这允许您使自己的异步逻辑返回一个promise,然后您可以将任意数量的回调附加到:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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 );
});

注意,现在您的trackPage()返回了一个可以附加回调的对象?你也不必马上把它们装上。

1
2
3
4
5
6
7
8
9
var pageHit = trackPage().done(function( guid ) {
    alert("Page Hit GUID:" +guid );
});

$("button").click(function() {
    pageHit.done( function( guid ) {
        alert("Clicked on Page GUID:" + guid );
    });
});

另外,jQueryAjax模块也总是返回承诺,因此,如果您做出自己的逻辑返回承诺,那么所有Ajax内容的接口应该非常相似。

旁注:我想指出的是,你的var returnValue无论如何在错误的"范围"中。它需要在trackPage功能的外部范围内声明。即使有了这个修复,这个概念仍然不起作用。


因为您有异步调用,所以您试图编写代码的方式将不起作用(因为到目前为止,trackcode返回值中的return returnValue;尚未定义)。相反,您应该将回调传递到trackpage:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
});