如何正确等待调度事件完成?

时间:2020-03-31 16:19:54

标签: javascript ajax dom-events

这是我的代码:

当用户按下“提交”按钮时,将调用功能checkFieldsBeforeSubmit(最后一个)。它触发附加到所有表单输入或选择的focusoutchange事件(dispatchAllFormInputEvents()函数)。事件执行验证输入或选择的函数,并相应地更改“ isInputValid”字段的属性。然后,我测试所有字段以检查其isInputValid是否为假。

尽管在.then(之后执行了最后一个测试,但如果我不添加setTimeout,则会在事件结束前 执行我的测试。

setTimeout是骇人听闻的骇客吧?如何正确等待这些事件完成?

不是jQuery解决方案的首选。

    fieldOne = document.getElementById('form_field1');
    fieldOne.addEventListener('focusout', validateFieldOneInput, false);

    // this function validate fieldOne
    function validateFieldOneInput()
    {
        let idField = "form_field1";
        let field = document.getElementById(idField);
        let input = field.value;
        let codeError= "";

        fetchInfosForValidation(input).then( (infos) => {

            if ( ! checkIfFormatCorrect() ) return false;

            // [...] other checks

            toggleFieldStatus(true, field, infos, codeError); // valid input
            return true;
        });
    }

  // this is a test use by validating functions.
    function checkIfFormatCorrect() {
        // doing stuff. return true if correct, false otherwise
    }

    // this change the state of a field, show error message.
    function toggleFieldStatus(isInputValid, field, infos, codeError) {
        field.setAttribute('isInputValid', isInputValid);
        field.classList.remove('required-border');

        if ( ! isInputValid )
        {
            field.classList.add("required-border");
            showErrorMessage(infos.errors[codeError]);
        }
    }

    // ajax call to fetch info needed for validation.
    function fetchInfosForValidation(input) {
        return new Promise(function (resolve, reject) {
            $.ajax({
                url: "/my/Url",
                type: "POST",
                data: {
                    input: input,
                },
                success: function (result) {
                    resolve(result.infos);
                },
            });
        });
    }

    // trigger all the events of the form
    async function dispatchAllFormInputEvents() {
            $('[id^="form"]').each(function(index, el) {
                var fieldEvent = new Event('focusout');
                if ( el.nodeName == "SELECT" ) fieldEvent = new Event('change');
                this.dispatchEvent(fieldEvent);
            });
    }

    // function called when 'submit' is hit.
    async function checkFieldsBeforeSubmit()
    {
        dispatchAllFormInputEvents().then( () => {
            setTimeout( () => { // WOULD LIKE TO GET RID OF THIS
                let isFormValid = true;
                $('[id^="form"]').each(function(index, el) {
                    if ( $(this).attr("isInputValid") === "false" ) isFormValid = false;
                });
                console.log(isFormValid);
            }, 1000); // HORRIBLE HACK
        });

    }

0 个答案:

没有答案