AJAX 调用和表单提交之间的延迟

Delay between AJAX call and form submit

本文关键字:延迟 之间 表单提交 调用 AJAX      更新时间:2023-09-26

以下代码片段解释了一种情况:

function submitHandler(form) {
    return x(form) && y(form);
}

x 是验证表单的外部函数。如果表单未经过验证,则返回 false,如果已验证,则返回 false,如果已验证,则返回表单。

y 是一个函数,只有在表单经过验证时才应调用该函数。它进行 AJAX 调用,JSONP 类型。JSONP ajax 调用只能是异步的。

Y 在收到响应后在内部提交表单。 y 将始终返回 false。

我不确定 x 到底做了什么,但我可以确认 y 被调用了,但它里面的 AJAX 调用被取消了。

当我创建断点并在 firebug 调试模式下运行时,AJAX 调用成功。因此,我认为创建延迟可以解决问题。

有没有办法在 AJAX 调用后创建延迟?

更新:

函数 y:-

function y(jsonStr) {
    jQuery.ajax({
        url: url,
        contentType: 'application/json',
        dataType: 'jsonp',
        data: {
            jsonInfo: jsonStr,
            jsonpCallback: 'submitForm'
        }
    });
}

更新 2:

函数 x(已编辑)

function x(form) {
    clearError();
    var submitButton = null;
    var allowSubmit = true;
    // Some code
    for ( var i = 0; i < form.elements.length; i++) {
        var fld = form.elements[i];
        if (!validateField(fld)) {
            allowSubmit = false;
        }
    }
    if (allowSubmit) {
        if (!pageSubmitted) {
            pageSubmitted = true;
            // some code
            form.submit();
            if (submitButton != null) {
                submitButton.disabled = true;
                submitButton.value = getPleaseWaitMessage();
            }
        } else {
            allowSubmit = false;
        }
    }
    // Some code
    return allowSubmit;
}

像您建议的那样引入延迟是非常不可靠的(例如,当接收来自 AJAX 调用的响应所需的时间比延迟长时会发生什么?您应该采用基于回调的方法。例如:

标记:

<div id="progress" style="display: none">Just a moment...</div>
<form onsubmit="return submitHandler(this);">
  <!-- ... -->
</form>

这里有一个小的帮助程序类型,它将有助于维护 JSONP 调用和特定客户端回调之间的链接(例如,作为第二个参数传递给 y 的那个 - 进一步演示):

var JSONPCallbackDispatcher = {
  _callbacks: [],
  register: function(callback) {
    var token = new Date().getTime();
    this._callbacks[token] = callback;
    return token;
  },
  dispatch: function(token, args) {
    if (this._callbacks[token]) {
      this._callbacks[token](args);
      delete this._callbacks[token];
    }
  }
}
function submitForm(token, response) {
  JSONPCallbackDispatcher.dispatch(token, response);
}

现在,主要逻辑:

function submitHandler(form) {
  var ret = x(form); // This is synchronous
  if (ret) {
    progress(form, true);
    y($(form).serialize(), function (result) { 
      progress(form, false);
      if (!result.error) {
        form.submit();
      }
    });
  }
  return ret;
}
function y(payload, callback) {
  var url = '...', token = JSONPCallbackDispatcher.register(callback);
  $.ajax({
    url: url,
    contentType: 'application/json',
    dataType: 'jsonp',
    data: {
        jsonInfo: payload,
        jsonpToken: token,
        jsonpCallback: 'submitForm'
    }
  });
}
// Shows/hides the progress indicator, toggles form controls' "disabled" state.
function progress(form, val) {
  var inputs = $(form).find('input, button, select');
  $('#progress').toggle(val);
  if (val) {
    inputs.attr('disabled', 'disabled');
  } else {
    inputs.removeAttr('disabled');
  }
}

现在,服务器可以按以下形式将调用返回到submitForm

<script>
    submitForm([token received from "jsonpToken"], 
      { error: [was there an error?] });
</script>

这种方法的好处是,特定于调用的回调不会分布在客户端逻辑中,从调用方的角度来看,这看起来更像是一个承诺(因此,如果可能,您可以轻松地将 JSONP 方法与complete/success回调交换,而不会影响调用y的方式)。

希望这有帮助。

根据您的要求,您可以添加执行y(form)函数的延迟,如下所示:

function y(jsonStr) {
            jQuery.ajax({
                url: url,
                contentType: 'application/json',
                dataType: 'jsonp',
                data: {
                    jsonInfo: jsonStr,
                    jsonpCallback: 'submitForm'
                },
                success: function (dataCheck) {
                    setTimeout(function () {
                        // Do something after 1 seconds delay
                        return true;
                    }, 1000);
                }
            });
        }