开发者

Any way in JavaScript to avoid using setTimeout to execute a function right after another? Maybe with jQuery?

I'm using this code:

$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);

And I get a error ($fieldDropdown.data("zenfilter") is null) on the fourth line ($typeDropdown = getTypeDropdown...). This is because the getFieldDropdown didn't finished execution yet. How can I call the functions lineally? Thanks a lot.

Edit: Added the getFieldDropdown function:

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(fun开发者_Python百科ction(){
        $(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);
};

(addOptions, sortOptions and selectOptions are just a plugin's methods to manipulate selects easier, they don't do any AJAX)


I assume that getFieldDropdown is an asynchronous call, from your question (a definition for that function would make this question easier to answer).

JavaScript does execute in a single-threaded way; your problem is not that getFieldDropdown doesn't complete, your problem is that it initiates an asynchronous call and then returns. If you want to do work with the results of an asynchronous call, you have to provide that call a callback: a function to execute when it's done.

Assuming the callback is the second, currently un-provided argument to getFieldDropdown, you'd do something like this:

$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);
});

that lets you defer the execution of the stuff that relies on the results of the asynchronous call until those results are there.


Those functions are called synchronously. What's most likely happening is that getFieldDropdown(fieldData.field) is returning null, or the object that it returns doesn't have the zenfilter property defined internally.


You will need to edit getFieldDropdown in order to achieve this. Instead of making it execute serially, it is better to re-design so that it can accept a callback method to run when execution is finished. This is the standard way with 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);

}
);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜