jquery函数的行为不符合逻辑

jquery函数的行为不符合逻辑,jquery,Jquery,奇怪的函数行为。我在一个父函数中工作,以下是相关部分: $("select#" + prefix + "1_" + num).val(smart_cat_data['cat_lvl2_id']); Foundation.libs.forms.refresh_custom_select($("select#" + prefix + "1_" + num), true); console.log("initial value and change DONE");

奇怪的函数行为。我在一个父函数中工作,以下是相关部分:

   $("select#" + prefix + "1_" + num).val(smart_cat_data['cat_lvl2_id']);
     Foundation.libs.forms.refresh_custom_select($("select#" + prefix + "1_" + num), true);
     console.log("initial value and change DONE");
     $.when(populateDep.call($("select#" + prefix + "1_" + num)),
     console.log("loading dependent select DONE"),
     console.log("setting " + prefix + "2_" + num + " TO: " + smart_cat_data['cat_lvl3_id'])
     ).then(function(x){
     $("#" + prefix + "2_" + num + " > option").each(function() {
         console.log(this.text + ' ' + this.value);
     });

     $("select#" + prefix + "2_" + num).val(smart_cat_data['cat_lvl3_id']);
     Foundation.libs.forms.refresh_custom_select($("select#" + prefix + "2_" + num), true);
     console.log($("select#" + prefix + "2_" + num).val());
     });
这要求:

function populateDep(){
console.log('populateDep');
     id_in_str = $(this).attr('id');
console.log('PROCESSING:' + id_in_str);
     var ctrl = id_in_str.slice(0,3); // the second param is POSITION not LENGTH!
     var this_select = parseInt(id_in_str.slice(3,4), 10); // the second param is POSITION not LENGTH!
     var row = id_in_str.slice(5);

    $.getJSON("/cat_dropdowns",{parent_id: $(this).val(), required: '1', ajax: 'true'}, function(j){
      var options = '';
      for (var i = 0; i < j.length; i++) {
        options += '<option value="' + j[i].value + '">' + j[i].text + '</option>';
      }

    var next_select = ++this_select;
      $("select#" + ctrl + next_select + "_" + row).html(options);

                     $("#" + ctrl + next_select + "_" + row + " > option").each(function() {
                         console.log('populateDep: ' + this.text + ' ' + this.value);
                     });
      Foundation.libs.forms.refresh_custom_select($('#' + ctrl + next_select + "_"  + row), true);
      Foundation.libs.forms.assemble();
console.log('this should be after the selects but before the end');
    });
console.log('populateDep DONE');
}
但由于某些原因,populateDep中的console.log会在声明完成后打印。它扰乱了我选择的选项,不允许我按需要自动选择。这是新手的事吗?我错过什么了吗?我加入了一张萤火虫的图片,因为我认为这是最简单的

更新的populateDep:

function populateDep(){
console.log('populateDep');
     id_in_str = $(this).attr('id');
console.log('PROCESSING:' + id_in_str);
     var ctrl = id_in_str.slice(0,3); // the second param is POSITION not LENGTH!
     var this_select = parseInt(id_in_str.slice(3,4), 10); // the second param is POSITION not LENGTH!
     var row = id_in_str.slice(5);

    $.when($.getJSON("/cat_dropdowns",{parent_id: $(this).val(), required: '1', ajax: 'true'}, function(j){
      var options = '';
      for (var i = 0; i < j.length; i++) {
        options += '<option value="' + j[i].value + '">' + j[i].text + '</option>';
      }

    })).then(function(options){
    console.log('starting then');
    var next_select = ++this_select;
      $("select#" + ctrl + next_select + "_" + row).html(options);

     $("#" + ctrl + next_select + "_" + row + " > option").each(function() {
         console.log('populateDep: ' + this.text + ' ' + this.value);
     });
      Foundation.libs.forms.refresh_custom_select($('#' + ctrl + next_select + "_"  + row), true);
      Foundation.libs.forms.assemble();
      console.log('this should be after the selects but before the end');

    });
console.log('populateDep DONE');
}

现在,它似乎根本没有填充select。请注意,$.getJSON已经有一个回调,所以我对正在发生的事情感到非常困惑。

正如我在评论中解释的那样,您的方法中存在很多问题

试一试


您需要将promise对象传递给$。如果您不这样做,也可能是出现问题的原因,那么console.log应该在异步回调函数之前执行。基本上,回调是在任务$.getJSON完成后启动的,但由于是异步的,$.getJSON让您的其余代码在它启动并执行其任务时运行。@JasonNichols抱歉,我不明白。我希望populateDep中$.getJSON之后发生的所有事情都发生在$.getJSON完成之后。我应该在什么时候把它包起来吗?你可以看看我做的这件。。。。还要注意,populateDep DONE将在选择之后但在结束之前打印,因为您使用的是异步请求
$("select#" + prefix + "1_" + num).val(smart_cat_data['cat_lvl2_id']);
Foundation.libs.forms.refresh_custom_select($("select#" + prefix + "1_" + num), true);
console.log("initial value and change DONE");

populateDep.call($("select#" + prefix + "1_" + num)).done(function (x) {
    $("#" + prefix + "2_" + num + " > option").each(function () {
        console.log(this.text + ' ' + this.value);
    });

    $("select#" + prefix + "2_" + num).val(smart_cat_data['cat_lvl3_id']);
    Foundation.libs.forms.refresh_custom_select($("select#" + prefix + "2_" + num), true);
    console.log($("select#" + prefix + "2_" + num).val());
});

function populateDep() {
    console.log('populateDep');
    id_in_str = $(this).attr('id');
    console.log('PROCESSING:' + id_in_str);
    var ctrl = id_in_str.slice(0, 3); // the second param is POSITION not LENGTH!
    var this_select = parseInt(id_in_str.slice(3, 4), 10); // the second param is POSITION not LENGTH!
    var row = id_in_str.slice(5);

    return $.getJSON("/cat_dropdowns", {
        parent_id: $(this).val(),
        required: '1',
        ajax: 'true'
    }, function (j) {
        var options = '';
        for (var i = 0; i < j.length; i++) {
            options += '<option value="' + j[i].value + '">' + j[i].text + '</option>';
        }

        var next_select = ++this_select;
        $("select#" + ctrl + next_select + "_" + row).html(options);

        $("#" + ctrl + next_select + "_" + row + " > option").each(function () {
            console.log('populateDep: ' + this.text + ' ' + this.value);
        });
        Foundation.libs.forms.refresh_custom_select($('#' + ctrl + next_select + "_" + row), true);
        Foundation.libs.forms.assemble();
        console.log('this should be after the selects but before the end');
    });
}