JavaScript中有什么方法可以避免使用setTimeout一个接一个地执行函数?也许用jQuery?

JavaScript中有什么方法可以避免使用setTimeout一个接一个地执行函数?也许用jQuery?,javascript,jquery,Javascript,Jquery,我正在使用以下代码: $newFilter = getNewFilter(); $fieldDropdown = getFieldDropdown(fieldData.field); $newFilter.append($fieldDropdown); $typeDropdown = getTypeDropdown($fieldDropdown.data('zenfilter').fieldId, $fieldDropdown.val(), fieldData.type); $newFilt

我正在使用以下代码:

$newFilter = getNewFilter();

$fieldDropdown = getFieldDropdown(fieldData.field);
$newFilter.append($fieldDropdown);

$typeDropdown = getTypeDropdown($fieldDropdown.data('zenfilter').fieldId, $fieldDropdown.val(), fieldData.type);
$newFilter.append($typeDropdown);

$inputBox = getInputBox($typeDropdown.data('zenfilter').fieldId, $typeDropdown.data('zenfilter').fieldType, $typeDropdown.val(), fieldData.value);
$newFilter.append($inputBox);
第四行(
$typeDropdown=getTypeDropdown…
)出现错误(
$fieldDropdown.data(“zenfilter”)为null)。这是因为
getFieldDropdown
尚未完成执行。如何以线性方式调用函数?非常感谢

编辑:添加了getFieldDropdown函数:

getFieldDropdown = function (populateData) {
    var $hiddenInput, i, $obj;

    $hiddenInput = $('<input>', {
        name: defaults.paramName + '[' + nFilters + '][field]',
        type: 'hidden'
    });
    $obj = $('<select></select>', {
        'class': classesHash.individualField,
        name: defaults.paramName + '[' + nFilters + '][fakefield]'
    }).
    data('zenfilter', { fieldId: nFilters }).
    addOption(fieldOptions).
    sortOptions(true).
    selectOptions('').
    change(function(){
        $(this).nextAll('select, div.' + classesHash.individualInputContainer).detach();
        $(this).removeClass(classesHash.incompleteField).after(getTypeDropdown($(this).data('zenfilter').fieldId, $(this).val()));
        $(this).prev('input[type=hidden]').val(defaults.data[$(this).val()].fieldname);
    });
    if (populateData) {
        for (i = 0; i < defaults.data.length; i += 1) {
            if (defaults.data[i].fieldname === populateData) {
                $obj.selectOptions(String(i));
            }
        }
    }

    return $hiddenInput.add($obj);
};
getFieldDropdown=函数(populateData){
变量$hiddenInput,i,$obj;
$hiddenInput=$(''{
名称:defaults.paramName+'['+nFilters+'][field]',
类型:“隐藏”
});
$obj=$(''{
“类”:classesHash.individualField,
名称:defaults.paramName+'['+nFilters+'][fakefield]'
}).
数据('zenfilter',{fieldId:nFilters})。
添加选项(字段选项)。
分类(正确)。
选择选项(“”)。
更改(功能(){
$(this).nextAll('select,div.+classesHash.individualInputContainer).detach();
$(this).removeClass(classesHash.incompleteField).after(getTypeDropdown($(this).data('zenfilter').fieldId,$(this.val()));
$(this.prev('input[type=hidden]').val(defaults.data[$(this.val()]).fieldname);
});
如果(填充数据){
对于(i=0;i

(addOptions、sortOptions和selectOptions只是一个插件的方法,可以更轻松地操作选择,它们不做任何AJAX)

这些函数是同步调用的。最可能发生的情况是
getFieldDropdown(fieldData.field)
返回null,或者它返回的对象没有内部定义
zenfilter
属性。

根据您的问题,我假设
getFieldDropdown
是一个异步调用(该功能的定义将使这个问题更容易回答)

JavaScript确实是以单线程方式执行的;您的问题不是
getFieldDropdown
没有完成,而是它启动了一个异步调用,然后返回。如果您想处理异步调用的结果,您必须为该调用提供一个回调:一个完成后要执行的函数

假设回调是当前未提供的getFieldDropdown的第二个参数,您可以执行以下操作:

$fieldDropdown = getFieldDropdown(fieldData.field, function(){
    $newFilter.append($fieldDropdown);

    $typeDropdown = getTypeDropdown($fieldDropdown.data('zenfilter').fieldId,$fieldDropdown.val(), fieldData.type);
    $newFilter.append($typeDropdown);

    $inputBox = getInputBox($typeDropdown.data('zenfilter').fieldId,$typeDropdown.data('zenfilter').fieldType, $typeDropdown.val(), fieldData.value);
    $newFilter.append($inputBox);
});

这使您可以推迟依赖异步调用结果的内容的执行,直到这些结果出现为止。

您需要编辑getFieldDropdown以实现这一点。与其让它串行执行,不如重新设计,以便它可以接受回调方法,在执行完成时运行。这是jQuery的标准方式:

fieldDropdown = getFieldDropdown(fieldData.field, function () {

  $newFilter.append($fieldDropdown);

  $typeDropdown = getTypeDropdown($fieldDropdown.data('zenfilter').fieldId,   $fieldDropdown.val(), fieldData.type);
  $newFilter.append($typeDropdown);

  $inputBox = getInputBox($typeDropdown.data('zenfilter').fieldId,   $typeDropdown.data('zenfilter').fieldType, $typeDropdown.val(), fieldData.value);
  $newFilter.append($inputBox);

}
);

getFieldDropdown
是否进行AJAX调用以加载数据?是否确定这就是此处发生的情况?$typeDropdown.data('zenfilter')在哪里set?getFieldDropdown调用是否执行AJAX查询,随后为$typeDropdown设置数据。否则,我会说上面的所有内容都将同步并按顺序执行。我们需要getFieldDropdown的函数定义,以查看它是异步的,还是最有可能是同步的(在这种情况下,计时器根本帮不上忙)。你提出的问题有太多未知数,要想为你的问题提供解决方案就成了猜测工作——这不是很有效…@steve_c:$typeDropdown.data('zenfilter')设置在getTypeDropdown()中。没有AJAX调用。你是对的,Daniel($fieldDropdown.data('zenfilter')).fieldId为空。非常感谢。