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

时间:2011-10-15 18:14:49

标签: javascript jquery asynchronous

我有以下jQuery函数。我正在尝试返回alert();中显示的GUID值。警报工作正常,值已填充,但我似乎无法将其分配给变量并返回其值。

最终我需要在其他功能等中访问GUID值。我尝试的所有内容都只显示为undefined

我想做这样的事情:

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

2 个答案:

答案 0 :(得分:48)

所以,这个问题已被问了一百万次,我确信每个人(包括我自己)tried this once

这只是异步调用的本质,您不能将其结果用作return值。这就是为什么他们让你传递一个得到调用结果的函数,他们也不能return它!另请注意,elqTracker.pageTrack()函数调用立即返回,因此returnValue只是undefined

大多数人(请参阅dfsq的回答)通过引入回调函数作为参数来解决此问题。尝试了这个方法,并且确实如此 - 但是jQuery有$.Deferred。这允许您使自己的异步逻辑返回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 );
});

现在请注意,您的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 );
    });
});

此外,jQuery AJAX模块也总是返回promises,因此如果你自己创建逻辑返回promise,那么所有AJAX东西的接口应该非常相似。


作为旁注:我想指出你的var returnValue无论如何都处于错误的“范围”。它需要在trackPage函数的外部范围内声明。即使有了这个修复,这个概念仍然不起作用。

答案 1 :(得分:13)

由于你有异步调用,你尝试编写代码的方式不起作用(因为在trackCode返回值的return returnValue;时刻尚未定义)。相反,你应该将回调传递给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
});