如何避免3 ajax调用?

时间:2010-07-14 23:17:32

标签: jquery ajax synchronization

在您选择国家/地区后,我编写了一些过滤省/州选择字段的代码:

    var cache = {};

    function updateProvinceOptions($select, values, initial) {
            for(i in values) {
                    $select.append('<option value="'+values[i][0]+'">'+values[i][1]+'</option>');
            }
            $select.val(initial).trigger('change');
    }

    $('<select class="province" />').insertBefore('.province').change(function() { // insert select boxes beside hidden province inputs
            $(this).siblings('input.province').val($(this).val()); // update hidden input with current value
    });

    $('.country').change(function() {
            var $countrySel = $(this);
            var $provSel = $countrySel.parent().parent().next().children('td').children('select.province');
            var $provInput = $provSel.siblings('input.province');
            var country = $countrySel.val();
            var province = $provInput.val();

            $provSel.empty();
            if(country in cache) {
                    updateProvinceOptions($provSel, cache[country], province);
            }
            else {
                    $provSel.addClass('loading');
                    $.getJSON('/get-provinces.json', {'country':country}, function(provinces) {
                            $provSel.removeClass('loading');
                            cache[country] = provinces;
                            updateProvinceOptions($provSel, provinces, province);
                    });
            }
    }).trigger('change');

它甚至会缓解结果,因此,如果你选择加拿大,然后是美国,再选择加拿大,它就不必再次登上加拿大省份的服务器。但是,我在页面上同时显示其中的3个。当页面首次加载时,缓存中没有任何内容,因此所有3个em都命中服务器以获取省份列表,因为尚未返回任何ajax调用。

是否有一种相对简单的方法告诉它“等待”,如果该国家的ajax呼叫已在进行中?或者我应该打扰吗?

3 个答案:

答案 0 :(得分:2)

我想说可能会在缓存或方法之外的其他对象中添加一个属性来指示缓存当前是否正在加载。在调用ajax方法之前将值设置为true,然后在ajax调用的success函数中将其设置为false。如果确实如此,则跳过任何后续调用,直到该值为false。

只是一种可能的解决方案。

答案 1 :(得分:1)

没关系..在回应我的问题时再次回答了我自己的问题...毕竟添加“等待”队列并不难:

    var cache = {};
    var retrieving = {};

    function updateProvinceOptions($select, values, initial) {
            for(i in values) {
                    $select.append('<option value="'+values[i][0]+'">'+values[i][1]+'</option>');
            }
            $select.val(initial).trigger('change');
    }

    $('<select class="province" />').insertBefore('.province').change(function() { // insert select boxes beside hidden province inputs
            $(this).siblings('input.province').val($(this).val()); // update hidden input with current value
    });

    $('.country').change(function() {
            var $countrySel = $(this);
            var $provSel = $countrySel.closest('tr').next('tr').find('select.province');
            var $provInput = $provSel.siblings('input.province');
            var country = $countrySel.val();
            var province = $provInput.val();

            $provSel.empty();
            if(country in cache) {
                    updateProvinceOptions($provSel, cache[country], province);
            } else if(country in retrieving) {
                    retrieving[country].push($provSel);
            }
            else {
                    retrieving[country] = [$provSel]
                    $provSel.addClass('loading');
                    $.getJSON('/get-provinces.json', {'country':country}, function(provinces) {
                            $provSel.removeClass('loading');
                            cache[country] = provinces;
                            while(retrieving[country].length > 0) {
                                    $select = retrieving[country].pop();
                                    updateProvinceOptions($select, provinces, province);    
                            }                               
                    });
            }
    }).trigger('change');

答案 2 :(得分:0)

我想说这取决于用例。用户是否总是必须通过这些元素?如果是这样,我可能倾向于在页面加载时获取所有数据,甚至首先将数据与页面一起向下发送。

还取决于您要处理的项目数量,也许自动填充可能是更好的解决方案。

真的需要一个更好的感觉,让应用程序更强烈地提出建议