让代码同步运行,驻留在通过AJAX调用调用的函数中

时间:2016-12-27 20:42:12

标签: javascript jquery ajax asynchronous

我有一个下拉通知窗口,当我运行某些AJAX函数时,我会显示它,让我们简化它:

function notifyComplete(type, alert_el, response) {

    var msg = response.output;
    var result = response.result;

    // Update msg in alert box
    alert_el.text(msg);

    if (result == 'success') {
        alert_el.addClass('alert-success');
    } else {
        alert_el.addClass('alert-danger');
    }

    // Slide in alert box
    alert_el.addClass('visible');

}

......我可以这样称呼它:

var alert_el = $('#top_notify').find('.alert');

// Remove any additional classes added by a possible previous run
alert_el.removeClass('visible alert-success alert-info alert-danger alert-warning');

getAjaxData(loadUrl, dataObject, 'POST', 'json')

    .done(function(response) {
        notifyComplete(notify_type, alert_el, response);
    });

..如果有兴趣,这里是getAjaxData函数:

function getAjaxData(loadUrl, dataObject, action, type) {

    return jQuery.ajax({
        type: action,
        url: loadUrl,
        data: dataObject,
        dataType: type
    });

}

现在我要做的是找到一种方法来放置这段代码:

var alert_el = $('#top_notify').find('.alert');

// Remove any additional classes added by a possible previous run
alert_el.removeClass('visible alert-success alert-info alert-danger alert-warning');

......每当我想使用notifyComplete函数时,我都不必重复它。

显然,如果在AJAX块中总是调用notifyComplete,那么我就无法将它放在函数本身中,因为那样你就不能让通知盒滑动了在没有页面重新加载的情况下不止一次。

此外,我无法之后,因为下滑通知窗口的持续时间由CSS处理,因此JS不知道它何时完成。< / p>

我已经在 CodePen here上建立了一个当前的工作示例,但由于crossorigin.me的问题,它似乎已被打破

2 个答案:

答案 0 :(得分:1)

你有几个选择。

  1. 您可以在setTimeout功能中使用notifyComplete,将其放在最后并为其提供合理的时间,以便通知警告在显示后自动消失

    < / LI>
  2.   

    此外,我之后无法做到这一点,因为下滑通知窗口持续时间由CSS处理,因此JS不知道它何时完成。

    这是不正确的,您可以使用trantisitionendanimationend事件来检查CSS效果何时结束。如果您使用的是bootstrap之类的东西,则可以在alert元素中使用transitionend。

答案 1 :(得分:1)

如果您打算致电

var alert_el = $('#top_notify').find('.alert');

// Remove any additional classes added by a possible previous run
alert_el.removeClass('visible alert-success alert-info alert-danger alert-warning');
在每次$.ajax()来电之前

,您可以在$.ajax()

内的beforeSend getAjaxData函数中添加这些行
function getAjaxData(loadUrl, dataObject, action, type) {

    return jQuery.ajax({
        beforeSend: function(jqxhr, settings) {
                      var alert_el = $('#top_notify').find('.alert');
                      // Remove any additional classes added by a possible previous run
                      alert_el
                     .removeClass('visible alert-success alert-info alert-danger alert-warning');
        },
        type: action,
        url: loadUrl,
        data: dataObject,
        dataType: type
    });

}

如果您在$.ajax()调用后尝试拨打这两行,但在notifyComplete之前,您可以将一个函数数组传递给.done()

getAjaxData(loadUrl, dataObject, 'POST', 'json')
.done([
  function(response) {
    var alert_el = $('#top_notify').find('.alert');
    // Remove any additional classes added by a possible previous run
    alert_el
    .removeClass('visible alert-success alert-info alert-danger alert-warning');
  }
  , function(response) {
      notifyComplete(notify_type, alert_el, response);
  }
 ]);
  

如果我可以将函数名称作为回调传递而不是使用   匿名函数,因此不得不诉诸于if/else内部,   但显然还需要一种包含参数的方法   回调。

您可以使用Function.prototype.bind()将其他参数传递给命名函数集,作为beforeSend $.ajax()选项的值。包含逻辑以检查其他对象或值是否是传递的对象或jQuery jqxhr对象,它是beforeSend的默认第一个参数。

  function handleBeforeSend(args, jqxhr, settings) {
    console.log(args, jqxhr, settings);
    if (args.hasOwnProperty("additionalSettings")) {
      // do stuff with `args.additionalSettings`
    }
  }

  $.ajax({
    url:"/path/to/server/",
    type: "POST",
    beforeSend: handleBeforeSend.bind(null, {additionalSettings:[0,1,2]})
  });

jsfiddle https://jsfiddle.net/dackdrek/

在当前javascript

内实施
$().ready(function() {

  function handleBeforeSend(bool, jqxhr, settings) {
    console.log(bool, jqxhr, settings);
    if (bool === true) {
      var alert_el = $('#top_notify').find('.alert');
      // Remove any additional classes added by a possible previous run
      alert_el.removeClass('visible alert-success alert-info alert-danger alert-warning');
    }
  }

  function notifyComplete(type, alert_el, response) {

    var msg = response.output;
    var result = response.result;

    // Update msg in alert box
    alert_el.text(msg);

    if (result == 'success') {
      alert_el.addClass('alert-success');
    } else {
      alert_el.addClass('alert-danger');
    }

    // Slide in alert box
    alert_el.addClass('visible');

  }

  function getAjaxData(loadUrl, dataObject, action, type, beforeSend, bool) {

    return jQuery.ajax({
      type: action,
      url: loadUrl,
      data: dataObject,
      dataType: type,
      beforeSend: beforeSend.bind(null, bool)
    });

  }
  // pass `true` to `handleBeforeSend`
  getAjaxData("/echo/json/", {
      json: JSON.stringify({
          "output": "123",
          "result": "success"
        })
      }, "POST", "json", handleBeforeSend, true)
    .then(function(response) {
      notifyComplete(null, $('#top_notify'), response)
    });
  setTimeout(function() {
  // pass `false` to `handleBeforeSend`
  getAjaxData("/echo/json/", {
      json: JSON.stringify({
          "output": "123",
          "result": "success"
        })
      }, "POST", "json", handleBeforeSend, false)
    .then(function(response) {
      notifyComplete(null, $('#top_notify'), response)
    })
   }, 5000)
})

jsfiddle https://jsfiddle.net/dackdrek/4/