jquery execute function when two conditions are met

人盡茶涼 提交于 2019-12-11 01:49:38

问题


I need to execute a specific function mvFinishItUp() when two conditions are met. More specifically, one condition is the callback success of a $.ajax the other is a normal flow of the code until it reaches the function. Kinda of this:

$.ajax({
    url: mv_finalUrl,
    success: function (data) {
        mvFinishItUp(data);
    },
    dataType: 'html'
});

/* here a lot more code, with animations and some delays */

mvFinishItUp(data) {
    /* My function code */
    /* But this code must only run after it has been called via the call back
       and after all the other code has been ran as well */
}

So, the function must wait for all the code if the ajax callback is quicker, or the other way around. Any ideas on how this could be implemented?

I'm willing to change the whole concept of script code, as I believe the loose code between the ajax, and the function itself should go to a function aswell ...


回答1:


This is a perfect use case for jQuery Deferred objects.

Remove the success: parameter from the AJAX call, and register the handler later:

var jqxhr = $.ajax(...); 

// do some other synchronous stuff
...

// and *then* register the callback
jqxhr.done(mvFinishItUp);

Deferred objects cope perfectly well (by design) with being registered on an AJAX event after that event already finished.




回答2:


Try like below, (It is just psuedo code)

var isAJAXDone = false, isFunctionCodeDone = false;
$.ajax({
  //..
  success: function () {
     isAJAXDone = true;
     mvFinishItUp(data, isAJAXDone, isFunctionCodeDone);
  } 
});

//..Your function code
//..Add this below the last line before the function ends
isFunctionCodeDone = true;
mvFinishItUp(data, isAJAXDone, isFunctionCodeDone);


//..
mvFinishItUp(data, isAJAXDone, isFunctionCodeDone ) {
   if (isAJAXDone && isFunctionCodeDone) {
      //Do your magic
   }
}



回答3:


Maybe something like this would do the trick:

var _data = undefined;

$.ajax({
    url: mv_finalUrl,
    success: function (data) {
        _data = data;
        myFinishItUp(data); // call the function from here if it's faster
    },
    dataType: 'html'
});

/* here a lot more code, with animations and some delays */

function myFinishItUp(data) {
    this.data = data; // store the data from the AJAX call or the code, whichever reaches first 
                      // if the code reaches this before the AJAX call completes, data will be undefined
    if(typeof this.wasCalled == "undefined") {
        /* My function code */
        /* But this code must only run after it has been called via the call back
           and after all the other code has been ran as well */
        this.wasCalled = true;
    }
}(_data); // function that calls itself when the code gets to this point with a self-contained boolean variable to keep track of whether it has already been called 

I used a self calling function execute when the code flow gets to that point, but if it's called from the AJAX call, it won't execute. It keeps track of whether or not it's already been called with a self-contained boolean value.




回答4:


Here I add an second parameter to check callback check

 function mvFinishItUp(data, byCallback) {

    var iscallback = byCallback || false; // if you don't send byCallback
                                          // default will false
    if(iscallback) {
       // execute if called by callback
    }
 }

 success: function (data) {
        mvFinishItUp(data, true); // call with second parameter true
 },

To execute mvFinishItUp() after ajax done and all codes between ajax and mvFinishItUp finished you can do something like this:

var allFunctionExecuted = false; // global to detect all code execution

$.ajax({
    url: mv_finalUrl,
    success: function (data) {
        mvFinishItUp(data, true);
    },
    dataType: 'html'
});

function func1() {

}

function func2() {

}

// some other code

function func3() {
    allFunctionExecuted = true;
}

Now,

 function mvFinishItUp(data, byCallback) {

    var iscallback = byCallback || false; // if you don't send byCallback
                                          // default will false

    if(iscallback && allFunctionExecuted) {

       // execute if ajax done
       // and others code done
    }
 }



回答5:


This is very "ugly" code, but you can modify it to not use global vars, so this is just illustrative:

var ajaxExecuted = false,
    codeExecuted = false;

$.ajax({
    url: mv_finalUrl,
    success: function (data) {
        ajaxExecuted = true;
        mvFinishItUp(data);
    },
    dataType: 'html'
});

/* here a lot more code, with animations and some delays */
codeExecuted = true;

mvFinishItUp(data) {
    /* My function code */
    if(ajaxExecuted && codeExecuted) {
      /* But this code must only run after it has been called via the call back
         and after all the other code has been ran as well */
    }
}

I just added two flags: ajaxExecuted and codeExecuted, and inside the function an if statement that checks the value of the those flags, and executes only when the two of them are set to true. So no mather who calls it first, it get only executed when the two flags are set to true.

A cleaner way could be to implement the function in an object, and use properties instead of global vars.



来源:https://stackoverflow.com/questions/10852561/jquery-execute-function-when-two-conditions-are-met

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!