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

时间:2013-12-19 08:02:20

标签: javascript jquery

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

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

x是一个验证表单的外部函数。如果未验证表单,则返回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;
}

2 个答案:

答案 0 :(得分:3)

像你建议的那样引入延迟是非常不可靠的(例如,当从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>

这种方法的优点在于,您的特定于呼叫的回调不会传播到客户端逻辑中,而且从调用者角度来看,这看起来更像是 promise (因此您可以轻松地尽可能使用complete/success回调交换JSONP方法,而不影响y的调用方式。

希望这有帮助。

答案 1 :(得分:0)

根据您的要求,您可以延迟执行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);
                }
            });
        }