Подтвердить что ты не робот

Асинхронное возвращаемое значение/присвоение JavaScript с помощью jQuery

У меня есть следующая функция 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();
4b9b3361

Ответ 1

Итак, этот вопрос задан в миллион раз, и я уверен, что все (включая меня) пробовали это раз.

Это просто характер асинхронного вызова, вы не можете использовать их результаты как значение return. Вот почему они передают вам функцию, которая получает результат вызова, они тоже не могут return! Также обратите внимание, что вызов функции elqTracker.pageTrack() возвращает НЕМЕДЛЕННО, поэтому ваш returnValue просто undefined.

Большинство людей (см. ответ dfsq) решают эту проблему, вводя функцию обратного вызова в качестве параметра. Этот метод проверяется, и true – однако 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, поэтому интерфейс для всех ваших файлов AJAX должен быть очень схожим, если вы вернете свою собственную логическую ссылку promises.


В качестве побочного примечания: я хотел бы указать, что ваш var returnValue был в неправильной области видимости. Его нужно было объявить во внешней области функции trackPage. Даже с этим исправлением концепция все еще не работает.

Ответ 2

Поскольку у вас асинхронный вызов, как вы пытаетесь написать код, он не будет работать (потому что к моменту 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
});