在事件监听器中触发函数之前等待异步调用完成

时间:2018-01-20 20:36:28

标签: javascript jquery asynchronous

我正在与一个设计了一系列.js脚本的网络项目进行合作,这些脚本的行为类似于“插件”,因为他希望这些脚本能用于其他网络项目。

这些“插件”大多数都是基于事件监听器的,它们会监听具有某些“数据”属性的元素的点击。例如,带有'data-setdata'的元素将在点击时触发'setdata.js'中的侦听器:

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

但其中一个插件'ajax.js'会激活一个'post'调用AJAX样式的内容加载:

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

... 所以当然我们发现自己处于无法控制'setdata.js'和'ajax.js'的顺序的情况。

我最初的想法是将这些插件恢复到函数中,并使用主要.js上的promises正确链接它们

但是,有没有办法延迟在事件监听器中触发函数,直到满足某个异步操作为止?伪代码:

{{1}}

谢谢

3 个答案:

答案 0 :(得分:1)

您可以使用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)
  }
});

答案 1 :(得分:0)

如本回答所述: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();

当然,这不是正确的做法,这将是承诺的链接。

但是在我描述的特定案例场景中,其他人强加了设计限制,并且当我已经告诉过此人时,但仍需要找到临时解决方法,这是正确的答案

答案 2 :(得分:0)

您应该使用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 
    }
});