How can I add this function to an array without it

2019-08-10 02:11发布

问题:

I have an array of functions that return jQuery deferred AJAX objects called phoneAjaxCalls. My code pushes multiple calls to a function called newPhone that accepts two arguments.

function newPhone(tlcPhone, studentsdcid) {
    //Create new email
    return $j.ajax({
        type: 'POST',
        url: '/admin/changesrecorded.white.html',
        data: tlcPhone
    });
}

I try to add calls to newPhone to phoneAjaxCalls with this code,

phoneAjaxCalls.push(newPhone(tlcPhone, stagingFormPhone.studentsdcid));

Then later in my code, I use

$.when.apply($j, phoneAjaxCalls).done(function () {
  //all phoneAjaxCalls MUST be complete before this code runs
  //Redirect to a different page by changing window.location
});

to resolve the array of jQuery deferreds.

By using breakpoints in DevTools, I have found that instead of calling newPhone when $.when is called, but when .push is called.

How can I add calls to newPhone to the phoneAjaxCalls array without it being called immediately?

The bug I'm seeing is that the page is getting redirected before all of the calls in phoneAjaxCalls can be completed.

If you'd like to see my entire codebase, it can be seen here. It's horribly messy, since it was a rushed project. Any other feedback is welcome as well, here or on Github. The file in question can be found here.

回答1:

You can use bind :

phoneAjaxCalls.push(newPhone.bind(window, tlcPhone, stagingFormPhone.studentsdcid));

and then change your call to $.when in order to really call the functions returning the needed promises:

$.when.apply($j, $.map(phoneAjaxCalls, $.call.bind($.call)).done(function () {

or, in a more readable way:

$.when.apply($j, $.map(phoneAjaxCalls, function(f){ return f() }).done(function () {

But this construct looks like a hack, do you really need to store functions instead of structured arguments or instead of executing the ajax calls as soon as possible ?

The normal way to use promises is the one you show in the question : the callback you pass to done does wait for the promises to be fullfiled.