2017-04-03 2 views
3

Ich versuche d3.json() innerhalb einer Funktion zu verwenden, um Daten Spotify API einen Künstler-ID (wie 5K4W6rqBFWDnAN6FQUkS6x) gegeben zurückzukehren, aber ich kann nicht herausfinden, wie effektiv die Daten zurückzukehren. Die Funktion sieht aus wied3 - Kann keine Daten von json Anfrage zurückgeben?

// Get artist's related artist's information 
function relatedArtists(id){ 
    var jsonPromise = new Promise(function(resolve, reject) { 
    // Async JSON request 
    d3.json('https://api.spotify.com/v1/artists/' + id + '/related-artists', function(error, data){ 
     if(error) reject(error); 
     resolve(data.artists); 
    }); 
    }); 

    jsonPromise.then(function(success) { 
    console.log(success); 
    //return(success) //doesn't work 
    }); 

    jsonPromise.catch(function(error){ 
    console.error(error); 
    }); 

} 

Ich habe versucht, eine Variable in der Funktion zu schaffen und dann zu modifizieren

function relatedArtists(id){ 
    var testVar = 'hello'; 
    var jsonPromise = new Promise(...{ 
    // Async JSON request 
    d3.json(...) 
    }); 
    jsonPromise.then(function(success) { 
    testVar = success; 
    }); 
    return(testVar); 
} 

Aber testVar bleibt 'hello', trotz all meiner Bemühungen. Ich habe etwas über den Umfang und die Versprechungen gelesen, bin aber froh, mehr zu tun, wenn es eine Kernmechanik von beiden gibt, die ich nicht verstehe. Danke fürs Lesen!

Antwort

3

Sie können Promise zurückkehren und verwenden relatedArtists Funktion wie so

function relatedArtists(id) { 
 
    return new Promise(function(resolve, reject) { 
 
    d3.json('https://api.spotify.com/v1/artists/' + id + '/related-artists', function(error, data) { 
 
     if (error) { 
 
     \t reject(error); 
 
     } else { 
 
     \t resolve(data.artists); 
 
     } 
 
    }); 
 
    }); 
 
} 
 

 

 
relatedArtists('5K4W6rqBFWDnAN6FQUkS6x') 
 
    .then(function (data) { 
 
    console.log(data); 
 
    }) 
 
    .catch(function (error) { 
 
    console.log(error); 
 
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

In diesem Fall können Sie den Wert testVar nicht zuordnen, weil d3.json die asynchrone Methode ist und das bedeutet, dass d3.json kann nach der Codeausführung ausgeführt werden. Art der Anfragen

4

Die Antwort wird nie aufgrund asynchron in Ihrem Telefonvorwahl zur Verfügung. Sie können Promises verwenden (wie angeblich von Alexander T. und Sie, eine gute Wahl in vielen Fällen!), Aber d3.queue macht einen guten Job, auch. In meinem Snippet können Sie sehen, wie Sie Code mit den Ergebnissen mehrerer Anfragen ausführen.

function buildRelatedArtistUri(id) { 
 
    return 'https://api.spotify.com/v1/artists/' + id + '/related-artists'; 
 
} 
 

 
d3.queue() 
 
    .defer(d3.json, buildRelatedArtistUri('5K4W6rqBFWDnAN6FQUkS6x')) 
 
    .await(function(error, data) { 
 
    // data and data.artists are available in this function‘s scope only 
 
    console.log(data.artists); 
 
    }); 
 

 
d3.queue() 
 
    .defer(d3.json, buildRelatedArtistUri('5K4W6rqBFWDnAN6FQUkS6x')) 
 
    .defer(d3.json, buildRelatedArtistUri('3nFkdlSjzX9mRTtwJOzDYB')) 
 
    .await(function(error, data1, data2) { 
 
    // this function will be called once both functions have finished 
 
    console.log(data1.artists, data2.artists); 
 
    });
<script src="https://d3js.org/d3.v4.min.js"></script>

+0

Oh, das ist wirklich cool-so 'd3.queue' ist eine Möglichkeit, Aktionen aufzuschieben, bis eine Anforderung abgeschlossen? Das scheint wirklich nützlich zu sein, danke! –

+0

Ja, können Sie jede Rückrufraubend async Funktion verschieben. Hinzu kommt, können Sie [Gleichzeitigkeit] (https://github.com/d3/d3-queue/blob/master/README.md#queue) und machen Aufgaben [abbrechbare] (https://github.com/d3 konfigurieren /d3-queue/blob/master/README.md#queue_abort)... – undko