我正在尝试d3.json()在函数内部使用给定艺术家ID(例如5K4W6rqBFWDnAN6FQUkS6x)的Spotify API返回数据,但我不知道如何有效地返回数据。该功能看起来像
// 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);
});
}
Run Code Online (Sandbox Code Playgroud)
我试过在函数中创建变量,然后对其进行修改
function relatedArtists(id){
var testVar = 'hello';
var jsonPromise = new Promise(...{
// Async JSON request
d3.json(...)
});
jsonPromise.then(function(success) {
testVar = success;
});
return(testVar);
}
Run Code Online (Sandbox Code Playgroud)
尽管我尽了最大努力,但testVar仍然如此'hello'。我已经阅读了一些有关范围和承诺的文章,但是如果有一些我不理解的核心机制,我很乐意做更多的事情。谢谢阅读!
由于请求的异步性质,响应在您的调用代码中将永远不可用。您可以使用Promises(正如Alexander T.和您所设想的那样,在许多情况下是个不错的选择!),但d3.queue也做得很好。在我的代码片段中,您可以看到如何使用多个请求的结果来运行代码。
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);
});Run Code Online (Sandbox Code Playgroud)
<script src="https://d3js.org/d3.v4.min.js"></script>Run Code Online (Sandbox Code Playgroud)