1

AJAX 呼び出しからデータを返し、ユーザーにクレジットが残っているかどうかを判断し、それに応じてデータを表示する関数があります。奇妙なことは、関数が期待される結果を返さないことです。コードは次のとおりです。

function setupBuildInputs() {
    noCreditsError = '<div class="alert alert-danger">You have no build credits remaining, please contact a representative to purchase more.</div>';

    if ( $('#newWebsiteBuildForm #user_id').length ) { 
        $('#newWebsiteBuildForm #user_id').change(function () {
            userID = $(this).val();
            jQuery.get(SITE_URL + '/ajax.php?action=getBuildCreditsRemaining&id=' + userID, function(numOfCredits) {
                if ( numOfCredits > 0 ) {
                    // Get latest website URL and show it on the page
                    $('#websiteURLHolder').html('Updating...');
                    jQuery.get(SITE_URL + '/ajax.php?action=getNextWebsiteUsername&id=' + userID, function(data) {
                        $('#websiteURLHolder').html(data + '.checkoutyournewsite.com');
                    });
                } else {
                    $('#quickBuildTagsHolder').html( noCreditsError );
                }
            });
        }); 
    }
    $('#newWebsiteBuildForm #template').change(function () {
        // Show the build form items
        numOfRemainingCredits = checkBuildCredits( $('#newWebsiteBuildForm #user_id').val() );
        alert(numOfRemainingCredits);

        if ( numOfRemainingCredits > 0 ) {
            $('#quickBuildTagsHolder').html('Updating...');
            jQuery.get(SITE_URL + '/ajax.php?action=returnQuickBuildTags&template=' + $(this).val(), function(data) {
                $('#quickBuildTagsHolder').html(data);
            });
        } else {
            $('#quickBuildTagsHolder').html( noCreditsError );
        }
    });
}
function checkBuildCredits( userID ) {
    buildCredits = 0;

    jQuery.get(SITE_URL + '/ajax.php?action=getBuildCreditsRemaining&id=' + userID, function(data) {
        buildCredits = data;
    });

    return buildCredits;
}

setupBuildInputs();

firebug を使用すると、ajax.php?action=getBuildCreditsRemaining への呼び出しがページから正しい ID を取得し、正しい値 (9999) を返すことがわかります。さらにデバッグするために、2 番目の変更イベント ハンドラーにアラートを追加したところ、結果が 9999 ではなく 0 として返されました。

次に、checkBuildCredits 関数を追加しても 2 つのアラートを追加しました。1 つ目は、ajax 呼び出しが機能し、そのデータが 9999 に設定されていることを確認しました。2 つ目は、奇妙なことに、関数が戻る直前に buildCredits がまだ 0 に設定されていることを示しています。

setupBuildInputs 関数では、最初の変更ハンドラーは同じ ajax 呼び出しを使用し、正常に動作します。関数を使用する 2 番目の変更ハンドラーは、9999 を取得せず、代わりに 0 を参照するため、もちろん失敗します。

ここで何が起こっているのですか?

4

3 に答える 3

0

jquery.get はデフォルトで非同期です。したがって、データを取得する前に、関数は関数で 0 値を返しますcheckBuildCredits

于 2013-10-21T14:19:25.190 に答える
0

Instead of $.get() try using the following:

$.ajax({
    url: SITE_URL + '/ajax.php?action=getBuildCreditsRemaining&id=' + userID,
    success: function(data) {
        buildCredits = data;
    },
    asynch: false
});

This will wait for the ajax call to complete before continuing script execution.

于 2013-10-21T14:27:52.050 に答える
0

replace checkBuildCredits with this

function checkBuildCredits( userID, successFn ) {


jQuery.get(SITE_URL + '/ajax.php?action=getBuildCreditsRemaining&id=' + userID, function(data) {
    successFn(data);
});

}

Then when you call checkBuildCredits, do it like this

checkBuildCredits( $('#newWebsiteBuildForm #user_id').val(), function(numOfRemainingCredits )
{
 if ( numOfRemainingCredits > 0 ) {
        $('#quickBuildTagsHolder').html('Updating...');
        jQuery.get(SITE_URL + '/ajax.php?action=returnQuickBuildTags&template=' +   $(this).val(), function(data) {
            $('#quickBuildTagsHolder').html(data);
        });
    } else {
        $('#quickBuildTagsHolder').html( noCreditsError );
    }

});

As the others have explained it, jquery.get is Asynchronous. And based on your design, you are treating jquery.get as a Synchronous call.

于 2013-10-21T14:28:09.540 に答える