AJAX Jquery: порядок выполнения событий - PullRequest
0 голосов
/ 30 ноября 2011

У меня есть веб-страница с различными элементами (списком ссылок и двумя полями выбора), связанными между ними. Нажатие на них может повлиять на один из других элементов, и все их значения способствуют обновлению значения, отображаемого на странице.

Итак, код такой:

$(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 ]

2 голосов
/ 30 ноября 2011

Есть несколько способов сделать это.

Вы можете использовать jQuery $. Когда и вызывать console.log после завершения ответа ajax.

$(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 голос
/ 30 ноября 2011

'second' console.log() вызывается первым, поскольку асинхронный вызов $.getJSON() ожидает ответа от сервера, прежде чем запустить его функцию обратного вызова. Вы можете сохранить объект jqXHR в переменной, а затем использовать его для запуска вашего «второго» * ​​1003 * с $.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

Небольшое примечание: как правило, медленнее добавлять тип тега к селектору, особенно когда вы выбираете идентификаторы, поскольку это уже очень быстрый способ выбора элементов.

0 голосов
/ 30 ноября 2011

Любой код, основанный на ответе 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();
    });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...