2016-06-29 10 views
1

Ich habe einen Kampf mit jQuery Defereds für mich zu arbeiten.jQuery Deferred Auflösung früh

ich Kette bin versucht, gemeinsam eine Reihe von Funktionsaufrufen, die $.ajax Anrufe mit jQuery .then Aussagen zu machen, mit dem Muster nachstehenden, aber jede Funktion zurückkehrt (und so die dann Kette fortsetzt), bevor der Ajax-Aufruf behoben .

// earlier code runs fine to here 
}) 
.then(function (r) { 
    getCurrentYearAbsenceRequestData(); // calls function which contains a $.ajax request 
}) 
.then(function (r) { 
    restructureCurrentYearAbsenceData(); 
}); 

// further processing of results 

Die oben genannten Funktionen folgen diesem Muster:

function getCurrentYearAbsenceRequestData() { 
var dfd = $.Deferred(); 

    var today = moment(); 
    var startOfCurrentHolidayYear = moment($clnt.holidayYearStartDate, "DD MMMM").format("DD/MM/YYYY"); 
    var startDayOfCurrentHolidayYear = moment().dayOfYear(startOfCurrentHolidayYear) 
    var currentDayOfYear = moment().dayOfYear(); 

    if (moment(today).isBefore(startOfCurrentHolidayYear)) { //checks if holiday year started last year 
     startOfCurrentHolidayYear = moment(startOfCurrentHolidayYear).subtract(1, "years"); //if so subtract 1 year from start of currently holiday year date 
    }; 

    console.log("Start of Holiday year is " + startOfCurrentHolidayYear); 

    var getOrgDataQuery = $apiUrl + "/web/lists/getbytitle('AbsenceRequests')/Items?$select=Id,AssocBranch/Title,DateFrom,DateTo,EmployeeLookup/EmployeeName,EmployeeLookup/Id,AbsenceType/AbsenceTypeShort,ReviewOutcome,TotalDays,AbsenceNotes&$expand=AssocBranch/Title,EmployeeLookup/EmployeeName,AbsenceType/AbsenceTypeShort&$filter=DateFrom ge '" + startOfCurrentHolidayYear + "'"; 

     $.ajax(_cnxRest.getRequest(getOrgDataQuery)) //calls personal library function which formats the parameter - this works OK) 
      .done(function (r) { 
       console.log("Get Org data success" + r); 
       var $absDataCurrentYearData = r.d.results; 
       $absData.allCurrentYear = $absDataCurrentYearData; 

      dfd.resolve(); 
      }) 
     .fail(function (err) { 
      logError(err); 
     }); 
    }; 

    return dfd.promise(); 

}; 

ich den $ .ajax Anruf bin zu wollen, die nachfolgende .then Funktion schreitet zu lösen, bevor und würde erfreut einige intelligente Beratung, wo erhalten Ich gehe falsch.

Antwort

1

Asynchrone Funktionen müssen ein Versprechen zurückgeben, um ihre Aufrufer über die Asynchronität zu informieren. Andernfalls wird die .then(...).then(...)-Kette eines Aufrufers ohne Rücksicht auf die Asynchronität fortgesetzt, was das in der Frage beschriebene Symptom ist.

Sie vermissen nur einige Rückgaben, obwohl der Code auch etwas aufgeräumt werden könnte.

// earlier code runs fine to here 
.then(function (r) { 
    return getCurrentYearAbsenceRequestData(); 
// ^^^^^^ 
}) 
.then(function (r) { 
    return restructureCurrentYearAbsenceData(); 
// ^^^^^^ 
}) 
.fail(function (err) { 
    logError(err); // by logging here you will see reported errors arising from the entire chain. 
}); 

function getCurrentYearAbsenceRequestData() { 
    var startOfCurrentHolidayYear = moment($clnt.holidayYearStartDate, "DD MMMM").format("DD/MM/YYYY"); 
    if(moment(moment()).isBefore(startOfCurrentHolidayYear)) { 
     startOfCurrentHolidayYear = moment(startOfCurrentHolidayYear).subtract(1, "years"); 
    }; 
    var getOrgDataQuery = $apiUrl + "/web/lists/getbytitle('AbsenceRequests')/Items?$select=Id,AssocBranch/Title,DateFrom,DateTo,EmployeeLookup/EmployeeName,EmployeeLookup/Id,AbsenceType/AbsenceTypeShort,ReviewOutcome,TotalDays,AbsenceNotes&$expand=AssocBranch/Title,EmployeeLookup/EmployeeName,AbsenceType/AbsenceTypeShort&$filter=DateFrom ge '" + startOfCurrentHolidayYear + "'"; 
    return $.ajax(_cnxRest.getRequest(getOrgDataQuery)) 
// ^^^^^^ 
    .then(function(r) { 
     $absData.allCurrentYear = r.d.results; 
     retrun r; // make the result available to the next step in the caller's .then chain, even if it's not going to be used 
//  ^^^^^^ 
    }); 
}; 

Die Hauptkette vereinfacht werden könnte: Hier

.then(getCurrentYearAbsenceRequestData) // calls function which contains a $.ajax request 
.then(restructureCurrentYearAbsenceData) 
.fail(function(err) { 
    logError(err); 
}); 

werden die Retruns diejenigen innerhalb der genannten Funktionen geschrieben.