AJAX Jquery:事件的执行顺序

时间:2011-11-30 17:34:12

标签: ajax event-handling jquery

我有一个网页,其中包含不同的元素(链接列表和两个选择框)。单击它们可能会影响其中一个元素,并且它们的所有值都有助于更新要在页面上显示的值。

所以,代码是这样的:

$(document).ready(function() {

    var someVar = '';

    $("select#size").bind('change', function() {
        someVar = $(this).val();
        console.log('first');
    });

    my_change();
    console.log('second' + someVar);
});

function my_change() {

    $.getJSON("photos/change_product", {json_stuff}, function(data) {
        var options = [];
        for (var i = 0; i < data.length; i++)  {
            options.push('<option value="' + data[i].id + '">' + data[i].label + '</option>');
        }
        $("select#size").trigger('change');
        $("select#options").html(options.join('')).trigger('change');
    })
};

};

当我加载页面时,调用my_change函数。它会执行一些操作,然后在选择框上触发change event。我需要使用此选择框中的内容更新值,然后让执行继续。所以我需要这个代码才能打印'first',然后'second'和变量的值。实际发生的是它打印'第二''第一'。

我认为这是因为我正在进行异步调用。我该怎么办?

3 个答案:

答案 0 :(得分:2)

有几种方法可以做到这一点。

你可以使用jQuery $.when并在ajax响应完成后调用console.log。

$(document).ready(function() {

    var someVar = '';

    $("select#size").bind('change', function() {
        someVar = $(this).val();
        console.log('first');
    });

    $.when( my_change() ).then(function(){ 
            console.log('second' + someVar);
    }); 
});

function my_change() {

    return $.getJSON("photos/change_product", {json_stuff}, function(data) {
        var options = [];
        for (var i = 0; i < data.length; i++)  {
            options.push('<option value="' + data[i].id + '">' + data[i].label + '</option>');
        }
        $("select#size").trigger('change');
        $("select#options").html(options.join('')).trigger('change');
    })
};

};

或者您可以向my_change(callback)函数添加回调参数。

$(document).ready(function() {

    var someVar = '';

    $("select#size").bind('change', function() {
        someVar = $(this).val();
        console.log('first');
    });

    my_change(function(){ console.log('second' + someVar) } ); 

});

function my_change(callback) {

    return $.getJSON("photos/change_product", {json_stuff}, function(data) {
        var options = [];
        for (var i = 0; i < data.length; i++)  {
            options.push('<option value="' + data[i].id + '">' + data[i].label + '</option>');
        }
        $("select#size").trigger('change');
        if( typeof callback !== 'undefined' && typeof callback === 'function' )
            callback(); 
        $("select#options").html(options.join('')).trigger('change');
    })
};

};

答案 1 :(得分:1)

首先调用'second'console.log(),因为异步$.getJSON()调用在触发其回调函数之前等待来自服务器的响应。您可以将jqXHR对象保存到变量中,然后使用它来运行带有consone.log()的“第二个”$.when()

$(function() {

    var someVar = '';

    $("#size").on('change', function() {//on() is the same as bind() here
        someVar = $(this).val();
        console.log('first');
    });

    //save the jQuery XHR object from your $.getJSON request
    var jqXHR = my_change();

    //when the above jQuery XHR object resolves, it will fire the second console.log
    $.when(jqXHR).then(function () {
        console.log('second' + someVar);
    });
});

function my_change() {

    //here we return the jQuery XHR object for the $.getJSON request so we can run code once it resolves
    return $.getJSON("photos/change_product", {json_stuff}, function(data) {
        var options = [];
        for (var i = 0; i < data.length; i++)  {
            options.push('<option value="' + data[i].id + '">' + data[i].label + '</option>');
        }
        $("#size").trigger('change');
        $("#options").html(options.join('')).trigger('change');
    })
};

以下是$.when()的文档:http://api.jquery.com/jquery.when

快速侧注:向选择器添加标签类型通常较慢,尤其是当您选择ID时,因为这已经是一种非常快速的选择元素的方法。

答案 2 :(得分:0)

任何依赖getJSON响应的代码都必须放在getJSON回调中,或从my_change回调中调用。

这就是回调的用途。

您应该注意,someVar函数无法访问ready()变量,因为它是my_change回调的本地变量。

要解决此问题,请在ready()回调中移动my_change功能。

或者直接将函数传递给my_change(function() { console.log('second' + someVar); });

getJSON

function my_change( func ) { $.getJSON("photos/change_product", {json_stuff}, function(data) { var options = []; for (var i = 0; i < data.length; i++) { options.push('<option value="' + data[i].id + '">' + data[i].label + '</option>'); } $("select#size").trigger('change'); $("select#options").html(options.join('')).trigger('change'); func(); }); } 回调调用函数。

{{1}}