当第三方javascript异步函数完成其执行时,调用自定义函数

时间:2013-06-22 18:58:38

标签: javascript jquery asynchronous promise

我有一个场景,我希望在特定的第三方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不是答案。

2 个答案:

答案 0 :(得分:2)

您没有真正的选择,只能民意调查以查看异步方法是否已完成。据推测,它可以改变一个你可以看到的状态,你可以以适当的频率进行轮询(我们称之为例程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库已经有一个处理轮询的例程。

答案 1 :(得分:0)

在我看来,这样可行......

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

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