2017-08-04 1 views
0

Ich habe einen API-Aufruf, der eine Liste von Bauabteilungen in Reihenfolge zurückgibt. Nach dem erfolgreichen Anruf wird ein zweiter API-Aufruf durchgeführt, um die Stunden jeder Abteilung abzurufen. Die Stunden werden dann für jede Abteilung in einer Tabelle gespeichert.AJAX-Strategie für laufende Aufgaben

Die API Aufrufe führen in der Tat die richtigen Stunden für die Abteilung und in der richtigen Reihenfolge geholt, aber die Erstellung der HTML-Tabellen zeigt die Liste der Abteilungen ist außer Betrieb, vermutlich aufgrund der asynchronen Art von AJAX.

Eine Probe console.log würde (für den ersten Anruf) sein:

getting area 3 which is in position 0 
getting area 10 which is in position 1 
getting area 8 which is in position 2 
getting area 9 which is in position 3 
getting area 7 which is in position 4 
getting area 6 which is in position 5 
getting area 5 which is in position 6 
getting area 4 which is in position 7 

Great! Beim Abruf der Stunden, aber die Reihenfolge nicht gilt:

Success for area 2 
Success for area 7 
Success for area 5 
... etc ... 

Die Abteilung Liste vollständig gezeigt aus, um auf der Seite. Beim Laden einer Seite konnte Bereich 8 zuerst angezeigt werden (Position 2). Und auf einer anderen, könnte Bereich 7 zuerst zeigen (Position 4). Hier

ist der erste Aufruf von Bereichen:

/** 
* Get the areas from the server 
* 
* @var bool Optionally display area hours for the week 
*/ 
function getAreas(displayAreas){ 
    ajaxObject = { 
     url: 'http://example.com/api/hoursrest/areas', 
     method: 'GET', 
     dataType: 'json', 
     xhrFields: { 
     withCredentials: true 
     }, 
     crossDomain: true, 
    } 
    $.ajax(ajaxObject) 
     .success(function(data,status,xhr) { 
      $('#main_hours').html(''); //clear previous hours 
      for(var i = 0; i < data.length; i++){ 
       //get and display the hours for this week 
       console.log("getting area " + data[i].id + " which is in position " + i) 
       getAreaHoursByWeek(data[i].id, today); 
      } 
     }) 
     .fail(function(data,status,xhr){ 
     }) 
     .always(function(data,status,xhr){ 
     }); 
} 

Und der nächste Anruf der Stunden zu holen:

/** 
* Get hours for a given area during a given week. 
* Specify a date and the hours for that date's week will be returned. 
* 
* @var int area The area's id. 
* @var String date The date in YYYY-mm-dd format 
*/ 
function getAreaHoursByWeek(area, date){ 
    //send area, start and end date to the server 
    ajaxObject = { 
     url: 'http://example.com/api/hoursrest/areadaterange', 
     method: 'GET', 
     dataType: 'json', 
     xhrFields: { 
     withCredentials: true 
     }, 
     crossDomain: true, 
     data: {'areaId': area, 'startDate': moment(date).startOf('week').format('YYYY-MM-DD'), 'endDate': moment(date).endOf('week').format('YYYY-MM-DD')} 
    } 
    $.ajax(ajaxObject) 
     .success(function(data,status,xhr) { 
      //display area's hours 
      console.log("Success for area " + area) 
      $('#main_hours').append(displayAreaHours(data)); //append area's hours to the main_hours div 
     }) 
     .fail(function(data,status,xhr){ 
     }) 
     .always(function(data,status,xhr){ 
     }); 
} 

Die Funktion, die die Tabelle assembliert nicht asynchron ist, aber hier ist der Stub zur Klarstellung.

/** 
* Display the hours for a given area 
* 
* @var JSON hours JSON formatted hours for an area 
*/ 
function displayAreaHours(hours){ 
    ... 
    return display; 
} 
+0

Mit welcher Reihenfolge beschäftigen Sie sich? Sicherstellen, dass das Gebiet in Ordnung ist oder dass der Erfolg in der gleichen Reihenfolge oder beides ist? – Taplar

+0

Letzteres; Die Reihenfolge, in der Bereiche abgerufen werden, muss der Reihenfolge entsprechen, in der sie letztendlich auf der Seite angezeigt werden. Wenn also nach den ersten Aufrufbereichen 1,2,3 in dieser Reihenfolge die Bereiche 1,2,3 in der Reihenfolge angezeigt werden müssen, in der ich auf der Seite – Ravioli87

+0

etwas verwendet habe, das wir chainer.js genannt haben. Sie haben im Grunde alle Methoden hinzugefügt, die Sie aufrufen möchten, und dann in der Erfolgsmethode eines Ajax nennen Sie 'chainer.next' und es würde den nächsten greifen. Es funktioniert gut für diese Art von Sache, hat aber Einschränkungen. – nurdyguy

Antwort

1

Sie möchten einen vielversprechenden Ansatz verwenden. Im Folgenden werden Beispieldaten aus https://jsonplaceholder.typicode.com/ verwendet, die über eine Sammlung von Benutzern verfügen und jeder Benutzer über eine Reihe von Inhaltsposts verfügt.

Im Grunde ist es eine Reihe von Anforderungs Versprechen für alle Benutzer Inhalte Beiträge Anfragen und verwendet $.when() erstellen ein Versprechen, das

löst nach

jsfiddle demo

function getUsers() { 
 
    return $.ajax({ // return $.ajax` promise 
 
    url: 'https://jsonplaceholder.typicode.com/users', 
 
    dataType: 'json' 
 
    }).then(function(users) { 
 
    // create array of request promises 
 
    var promises = users.map(getUserPosts); 
 
    // return promise that resolves when all request promises resolve 
 
    return $.when.apply(null, promises).then(function() { 
 
     // return updated users array to next then() 
 
     return users; 
 
    }); 
 
    }); 
 
} 
 

 
function getUserPosts(user) { 
 
    return $.ajax({ // return $.ajax` promise 
 
    url: 'https://jsonplaceholder.typicode.com/posts', 
 
    dataType: 'json', 
 
    data: { 
 
     userId: user.id, 
 
     _limit: 2 
 
    } 
 
    }).then(function(posts) { 
 
    console.log('Received posts userId:', user.id); 
 
    // add posts for this user as property of the user object 
 
    user.posts = posts; 
 
    return user; 
 
    }); 
 
} 
 

 
// start requests 
 
getUsers().then(processUsers) 
 
    .fail(function() { 
 
    console.log('Something went wrong in at least one request'); 
 
    }); 
 

 
function processUsers(users) { 
 
    console.log('All users done'); 
 
    var $cont = $('#container'); 
 
    // insert data in dom 
 
    $.each(users, function(_, user) { 
 
    var $div = $('<div>', {class: 'user'}); 
 
    $div.append('<strong>User Id:' + user.id + '<strong>'); 
 
    // loop over this user's posts 
 
    $.each(user.posts, function(_, post) { 
 
     $div.append($('<div>').text('Post Id : ' + post.id)) 
 
    }); 
 
    $cont.append($div) 
 
    }); 
 
}
.user { 
 
    border: 2px solid #ccc; 
 
    margin: 5px 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="container"></div>
gelöst haben alle die individuellen Anforderungen erstellt

Verwandte Themen