【问题标题】:Call a custom function when a third party javascript async function completes its execution当第三方 javascript 异步函数完成执行时调用自定义函数
【发布时间】:2013-06-22 18:58:38
【问题描述】:

我有一个场景,我希望在特定的第 3 方 js 函数完成执行后执行我的函数。

我无法编辑loadOne 的来源,但是我可以添加/覆盖我的newLoadOne 作为点击监听器。所以我可以代表它执行loadOne,并用它返回的数据执行我的代码。

现在,我的newLoadOneloadOne 方法的异步回调返回之前打印console.log

HTML

<select id="option1">
    <option>1</option>
    <option>2</option>
    <option>3</option>
</select>

<select id="option2">
    <option>One</option>
    <option>Two</option>
    <option>Three</option>
</select>

<input id="submit" type="button" value="Submit" />  

JavaScript

function loadOne(){
    someAsyncXhrMethod(with_its_own_parameters);//its own xhr method with aync callbacks 
}


function newLoadOne(){

    (function(){loadOne(); console.log('done');}());
}

function optionschanged(){
    console.log('options changed');
}

function bEvents(){
    $('#option1').change(optionschanged);
    $('#option2').change(optionschanged);
    $('#submit').bind('click', newLoadOne); //this is where i replace the call to loadOne with my newLoadOne
}

$(document).ready(function () {
    console.log('ready');
    bEvents();

});

这里是jsFiddle link - 注意: 源代码中的$.ajax 调用是为了解释loadOne 方法有一些异步回调。所以$(document).ajaxComplete 不是答案。

【问题讨论】:

  • 不幸的是,如果库的作者没有使这成为可能,那么您将无能为力(除了错误他们以修复他们的错误)。但是为什么不能编辑源代码?
  • 这是第三方源代码,我无法访问它。
  • 我们需要了解更多关于我认为的原始loadone 作品...看看是否有什么我们可以挂钩...
  • @Jivings ajaxComplete 仅在 3rd 方方法使用 jquery 时才有效,在我的情况下它不是。
  • 如果主题函数没有返回promise并且asych操作不是jQuery.ajax,那么你就很卡壳了。我并不是说不可能,但在能够提供建议之前需要了解更多。

标签: javascript jquery asynchronous promise


【解决方案1】:

您别无选择,只能轮询以查看异步方法是否已完成。据推测,它会以适当的频率更改您可以轮询的可见状态(我们将调用该例程check_some_async_xhr_method_completed)。

function newLoadOne () {
    loadOne (); 
    check_completion (function (completed) {
        console.log (completed ? 'done' : 'never finished');
    });
}

function check_completion (callback) {
    var number_of_tries = 20;
    var timer = setInterval (
        function () {
            if (check_some_async_xhr_method_completed ()) {
                clearInterval (timer);
                callback (true);
            } else if (!number_of_tries--) {
                clearInterval (timer);
                callback (false);
            }
        },       
        500
    );
}

或者,如果您更喜欢使用承诺:

function newLoadOne () {
    loadOne (); 
    check_completion ().then (
        function () {console.log ('done'),
        function () {console.log ('never finished')
    );
}    

function check_completion () {
    var promise = Promise.new();
    var number_of_tries = 20;
    var timer = setInterval (
        function () {
            if (check_some_async_xhr_method_completed ()) {
                clearInterval (timer);
                p.fulfill ();
            } else if(!number_of_tries--) {
                clearInterval (timer);
                p.reject ();
            }
        },       
        500
    );
    return promise;
}

或者,when 库已经有一个处理轮询的例程。

【讨论】:

  • 感谢您的回答。我有问题的xhr方法实际上是用新选项更新列表(html选择标签),我不得不重新格式化每个选项的显示字符串,设置/清除间隔例程的问题是人们无论如何都会注意到变化(如果xhr之前完成下一个间隔调用。处理选项更新肯定是不同的 SO 问题。并且 DOMSubtreeModified 被推迟:(
【解决方案2】:

在我看来这会起作用......

$(document).ajaxComplete(function (event, xhr, settings) {
  if ( settings.url === "the/url/that/loadone/uses" ) {
    // do your callback here
  }
});

抱歉,这仅在使用 jQuery 发出请求时有效。

【讨论】:

  • 这行得通吗?他没有使用 jQuery ajax 功能,所以这个处理程序会被调用吗?它实际上是否适用于非 jquery XMLHTTPRequests?
  • @prodigitalson 我实际上不知道也找不到指定的参考。我将模拟一个演示。
猜你喜欢
  • 2015-12-06
  • 1970-01-01
  • 1970-01-01
  • 2021-12-09
  • 1970-01-01
  • 2018-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多