简体   繁体   English

等待异步调用完成,然后在事件侦听器中触发功能

[英]wait for async call to finish before firing function in event listener

I am collaborating on a web project with someone who devised a series of .js scripts that act like 'plugins' in the sense that he would like them to be used on other web projects. 我正在与某人合作开发一个Web项目,该人设计了一系列.js脚本,这些脚本的作用类似于“插件”,因为他希望它们可以在其他Web项目中使用。

Most of these 'plugins' are event listener based, and they listen for clicks on elements with certain 'data' attributes. 这些“插件”大多数基于事件侦听器,它们侦听具有某些“数据”属性的元素的点击。 For example an element with 'data-setdata' will fire, on click, a listener in 'setdata.js': 例如,带有“ data-setdata”的元素将在单击时触发“ setdata.js”中的侦听器:

$('body').on('click', '[data-setdata]', function(e) {
  // do something
});

But one of these plugins, 'ajax.js', fires a 'post' call for AJAX-style loading of content: 但是其中一个插件“ ajax.js”触发了“后”调用,以AJAX样式加载内容:

$('body').on('click', '[data-ajax]', function(e) {
    $.post(
      //etc
    );
  }
});

... so of course we find ourselves in a situation in which we cannot control the order in wich 'setdata.js' and 'ajax.js' occur . ... 因此,我们当然处于无法控制'setdata.js'和'ajax.js'发生的顺序的情况下

My initial thought was to get those plugins back into functions, and properly chain them using promises on a main .js 我最初的想法是让那些插件恢复功能,并在主.js上使用promise正确链接它们

But, is there a way to delay firing the function within an event listener until a certain async action has been fulfilled? 但是, 是否有办法在事件监听器中延迟触发功能,直到完成某个异步操作为止? pseudocode: 伪代码:

$('body').on('click', '[data-setdata]', function(e) {
  when( ajax call finishes ){
    // do something
  }
});

Thank you 谢谢

You can use jQuery's ajaxComplete event 您可以使用jQuery的ajaxComplete事件

let done = false;

$(document).on("ajaxComplete", function(event, jqxhr, settings) {
  if (settings.url === "/path/to/resource" && !done) done = true;
});

$('body').on('click', '[data-setdata]', function(e) {
  if (done) {
    // do something
  } else {
    console.log(done)
  }
});

As explained in this answer: https://stackoverflow.com/a/22125915/5721273 I could use a setTimeout within the plugins, to continuously poll for changes on a flag set by the ajax call completion. 如此答案中所述: https : //stackoverflow.com/a/22125915/5721273我可以在插件中使用setTimeout,以连续轮询ajax调用完成设置的标志的更改。

function checkFlag() {
    if(flag == false) {
       window.setTimeout(checkFlag, 100); /* this checks the flag every 100 milliseconds*/
    } else {
      /* do something*/
    }
}
checkFlag();

Of course this is not the proper way of doing it, which would be chaining promises. 当然,这不是正确的方法,这可能会造成许诺。

But in the specific case-scenario that I described, in which there is a design limitation imposed by someone else, and when I already told this person about it, but still need to find a temporary workaround, this is the correct answer. 但是在我描述的特定案例场景中,其他人施加了设计限制,并且当我已经告诉此人此事但仍然需要找到临时解决方法时,这才是正确的答案。

You should use ajax's complete option, which executes when the call is completed, no matter if it is successful or not. 您应该使用ajax的complete选项,无论调用成功与否,该选项都会在调用完成后执行。

$.ajax({
    type: "GET",

    ....

    success: function(data) {
        // do some stuff
    },
    error: function(data) {
        // do other stuff stuff
    },
    complete: function(data) {
        // call your other function here 
    }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM