2016-10-23 6 views
0

In meiner Anwendung habe ich eine XML Datei, die zu verschiedenen API verbindet und sammelt Informationen. Dann zeigt es in einer div die abgerufene Information. Ich mache es erfolgreich, aber das Problem ist, die XML wird nicht geladen, wenn Element eins nach dem anderen. Es lädt Daten parallel, so dass die div s es erstellt nicht in der richtigen Reihenfolge wie sie in der xml Datei sind.So sortieren Sie die geladenen XML-Daten

Hier ist ein demo, die einige Daten von lokalen, SoundCloud, Spotify und iTunes erhalten.

Und das ist die XML file es aus wird geladen:

$.ajax({ 
 
    url: "https://dl.dropboxusercontent.com/u/33538012/text.xml", 
 
    dataType: "xml", 
 
    success: parse, 
 
    error: function() { 
 
    alert("Error"); 
 
    } 
 
}); 
 

 
function parse(document) { 
 
    var inc = 1; 
 

 
    $(document).find("track").each(function() { 
 
    var rowNum = inc; 
 
    var trackType = $(this).find('type').text(); 
 
    var trackTitle = $(this).find('title').text(); 
 
    var soundcloud_url = $(this).find('soundcloud_url').text(); 
 
    var spotify_track_uri = $(this).find('spotify_track_uri').text(); 
 
    var itunes_id = $(this).find('itunes_id').text(); 
 
    
 
    if (trackType == "audio") { 
 
     inc = inc + 1; 
 
     $(".playlist").append("<div id='" + rowNum + "' >" + rowNum + " " + trackTitle + "</div>"); 
 
     
 
    } else if (trackType == "soundcloud") { 
 
     inc = inc + 1; 
 
     SC.initialize({ 
 
     client_id: "b8f06bbb8e4e9e201f9e6e46001c3acb" 
 
     }); 
 
     SC.resolve(soundcloud_url).then(function(sound) { 
 
     trackTitle = sound.title; 
 
     $(".playlist").append("<div id='" + rowNum + "' >" + rowNum + " " + trackTitle + "</div>"); 
 
     }); 
 
     
 
    } else if (trackType == "spotify") { 
 
     inc = inc + 1; 
 
     var spotifyLink = "https://api.spotify.com/v1/tracks/" + spotify_track_uri; 
 
     $.getJSON(spotifyLink, function(data) { 
 
     trackTitle = data.name; 
 
     $(".playlist").append("<div id='" + rowNum + "' >" + rowNum + " " + trackTitle + "</div>"); 
 
     }); 
 
     
 
    } else if (trackType == "itunes") { 
 
     inc = inc + 1; 
 
     var iTuensLink = "https://itunes.apple.com/lookup?id=" + itunes_id + "&callback=?"; 
 
     $.getJSON(iTuensLink, function(data) { 
 
     trackTitle = data.results[0].trackName; 
 
     $(".playlist").append("<div id='" + rowNum + "' >" + rowNum + " " + trackTitle + "</div>"); 
 
     }) 
 
    } 
 
    
 
    }); 
 

 
}
<script src="https://connect.soundcloud.com/sdk/sdk-3.1.2.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div class="playlist"></div>

Wenn man sich das Ergebnis des Codes sehen, die die Zahl neben jeder Zeile zeigt die Reihenfolge, in der ursprünglichen XML Datei, aber sie werden nicht genau hintereinander geladen.

Kann ich die geladenen Dateien genau so sortieren, wie sie in der XML Datei geschrieben sind?

+0

Wenn ich mich nicht irre, erhalten Sie die XML in der richtigen Reihenfolge, es ist die Anforderungen, die Sie für jedes Online-Element, die nicht die gleiche Zeit nehmen. 'Dan' und' Sasy' werden jedes Mal auftauchen, weil du keine solche Anfrage stellst – Aaron

+0

@Aaron das ist richtig. Jedes Online-Item hat seine Antwort-Zeit und das macht die Divs unsortiert. Ich brauche eine Möglichkeit, sie zu sortieren. Vielleicht nachdem alle Daten gesammelt wurden. – DannyBoy

+1

dies erfordert eine Reihe von Versprechen erstellt werden und nur wenn sie alle gelöst sind, fügen Sie die Daten – charlietfl

Antwort

1

Sie DEFFERED Objekt verwenden können, die eine Erweiterung der Verheißung sind und auflösen kann es self.So sie als Auslöser, wenn

mit Entschlossenheit verwendet handeln kann

Crate ein Array, das unsere DEFFERED Objekte beachten Sie, dass Reihenfolge wichtig halten würde, ist daher ist numerisches Array gerade angelegt haben eine

DEFFERED
var dfd = jQuery.Deferred(); 

definieren, was auf

dfd.then(function(){ 
    $(".playlist").append("<div id='" + rowNum + "' >" + rowNum + " " + trackTitle + "</div>"); 
    }) 
getan werden sollteschieben Sie es schließlich auf unser Angebot

x.push(dfd) 

Nachdem alle api Anrufe werden über rufen Sie einfach resolve auf jeder

$.each(x, function(){ 
    this.resolve(); //then callback gets called one by one on each deffered 
}); 

https://jsfiddle.net/sanddune/rr7tord6/

Sie möchten vielleicht einen Mechanismus haben, wenn die langsamste Anruf zu erkennen endet und dann Anruf lösen

EDIT:

Die Latenz der einzelnen API variiert stark über die geographies zum Beispiel für mich Soundcloud war die "laggy", so dass es zuletzt endete aber für jemand anderen itunes kann der letzte sein, um dies zu beenden ist aufgrund vieler Variablen wie Entfernung vom Server, ISP , Throttling etc. so klar, dass Sie sich nie auf "Last Man Standing" Ansatz verlassen können, so könnte ich nur vorschlagen, dass eine Art von Zähler wie folgt verwenden, um zu verfolgen, wie viele Anfrage sind hervorragend

Erste erhalten insgesamt nicht.von Knoten (Inn xml), die eine API haben, sagen Sie haben Sie nur Soundcloud und shopify so jetzt total = 2; count = 0

so, wenn die api Anfrage Erträge erhöhen sie durch eine wie

$.getJSON(spotifyLink, function(data) { 
    trackTitle = data.name; 
    alert('shopify loaded'); 
    count++;check(); 
}); 

oder

SC.resolve(soundcloud_url).then(function(sound) { 
    trackTitle = sound.title; 
    alert('soundcloud loaded'); 
    count++;check(); 
}); 

beachten Sie, dass Sie auf einmal ausgefallen api Anfrage erhöhen müssen (die von schlechten Parameter führen usw. .)

rufen Sie eine Prüffunktion auf, die prüft, ob Anzahl == Summe bei jedem Erfolg/Fehler Teil der API-Anforderung

function check(){ 
    if(count==total) 
    alert('all api request finished'); 
    //resolve all deffereds 
} 
+0

Vielen Dank für Ihre Antwort. Es funktioniert perfekt. Das einzige Problem ist, dass der Vorgang nach dem Drücken der Schaltfläche ausgeführt wird. Ist es möglich, das Bit automatisch zu bearbeiten, sobald das Plugin geladen wird? Danke nochmal – DannyBoy

+0

Vielen Dank für Ihre Qualitätsantwort. In der Tat ist +1 nicht genug, um es als Antwort zu akzeptieren. – DannyBoy

Verwandte Themen