使代码同步运行,该代码驻留在通过AJAX调用调用的函数中 [英] Getting code to run synchronously that resides inside a function called via an AJAX call

查看:71
本文介绍了使代码同步运行,该代码驻留在通过AJAX调用调用的函数中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a dropdown notification window that I show when I run certain AJAX functions, let's simplify it as:

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

}

...我可能会这样称呼它:

...and I might call it like so:

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 函数:

..and here is the getAjaxData function if of interest:

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

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

}

现在我要尝试的是找到一种放置此代码的方法:

Now what I am trying to do is find a way I can place this code:

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 函数的地方都不必重复此操作.

...somewhere where I don't have to repeat it every time I want to use the notifyComplete function.

很显然,如果总是要在AJAX块中调用 notifyComplete ,那么我就不能将其放在函数本身中,因为那样便无法使通知框向下滑动在不重新加载页面的情况下不止一次.

Obviously if notifyComplete is going to be always called within an AJAX block then I can't put it inside the function itself as then you wouldn't be able to get the notify box to slide down more than once without a page reload.

此外,我不能在之后执行,因为向下滑动通知窗口的持续时间由CSS处理,因此JS不知道何时完成.

Also, I can't do it afterwards as the slide down notify window duration is handled by CSS and hence JS doesn't know when it's complete.

我已经在 CodePen 上构建了当前的工作示例,此处但似乎由于crossorigin.me的问题而被破坏了

I had built a current working example on CodePen here but it seems it's broken because of an issue with crossorigin.me

推荐答案

如果您要致电

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

before each $.ajax() call, you can include the lines within $.ajax() beforeSend function within 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()

If you are trying to call the two lines after $.ajax() call, though before notifyComplete you can pass an array of function to .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 但显然也需要一种在参数中包含参数的方式回调.

if I could pass it a function name as a callback rather than use an anonymous function and thus have to resort to using if/else inside, but obviously also need a way of including parameters with the callback.

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

You can use Function.prototype.bind() to pass additional parameters to a named function set as value of beforeSend option of $.ajax(). Include logic to check if the additional object or value is the passed object or jQuery jqxhr object that is the default first parameter of 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/

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/

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

这篇关于使代码同步运行,该代码驻留在通过AJAX调用调用的函数中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆