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

pat*_*ick 28 javascript jquery asynchronous

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

最终我需要在其他函数中访问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();
Run Code Online (Sandbox Code Playgroud)

gna*_*arf 49

所以,这个问题已经被问过一百万次了,而且我确信每个人(包括我自己)都试过一次.

它只是异步调用的本质,您不能将其结果用作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 );
});
Run Code Online (Sandbox Code Playgroud)

现在请注意,您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 );
    });
});
Run Code Online (Sandbox Code Playgroud)

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


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


dfs*_*fsq 14

因为你有异步调用,所以你试图编写代码的方式不会起作用(因为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
});
Run Code Online (Sandbox Code Playgroud)