3

I have a scenario where I would like my function to be executed after a particular 3rd party js function completes its execution.

I can't edit the source of loadOne however I could add/override my newLoadOne as on click listener. So I can execute the loadOne on its behalf and execute my code with the data it returns.

Right now, my newLoadOne prints console.log before the loadOne method's async callback return.

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

});

here is the jsFiddle link - Note: $.ajax call in the source is to explain the method loadOne has some async callbacks. So $(document).ajaxComplete is not the answer.

6
  • Unfortunately if the author of the library hasn't made this possible then there's nothing you can do about it (except bug them to fix their mistake). But why can't you edit the source? Commented Jun 22, 2013 at 19:03
  • It is 3rd party source code, I couldn't have access to it. Commented Jun 22, 2013 at 19:05
  • We'd need to know more about the original loadone works i think... To see if there is something we can hook in to... Commented Jun 22, 2013 at 19:09
  • 1
    @Jivings ajaxComplete works only if the 3rd party method uses jquery in my case it is not. Commented Jun 22, 2013 at 19:12
  • 1
    If the subject function does not return a promise and the asych operation is not jQuery.ajax, then you are very very stuck. I'm not saying impossible, but one would need to know a lot more before being able to advise. Commented Jun 22, 2013 at 19:16

2 Answers 2

2

You have no real choice but to poll to see if the async method has completed. Presumably it does something that changes a state which is visible to you that you can poll for (we'll call that routine check_some_async_xhr_method_completed), at some appropriate frequency.

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

Or, if you would prefer to use promises:

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;
}

Or, the when library already has a routine which handles polling.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for the answer. I xhr method in question is actually updating the list (html select tag) with new options, I had to reformat the display string of each options, issue with Set/clear Interval routine is people will notice the change in anyway (if xhr completed before the next interval call. Handling options update is definitely different SO question. And DOMSubtreeModified is deferred :(
0

It seems to me like this would work...

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

Sorry, this only works when the request is made using jQuery.

2 Comments

Will that work? He's not using the jQuery ajax functionality so will this handler ever be called? Does it actually apply to non-jquery XMLHTTPRequests?
@prodigitalson I actually have no idea and can't find a reference that specifies. I'll mock up a demo.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.