d3 - 无法从json请求返回数据?

时间:2017-04-03 14:21:03

标签: json ajax d3.js

我尝试在函数内部使用d3.json()返回数据Spotify的API给定艺术家ID(例如5K4W6rqBFWDnAN6FQUkS6x),但我不能弄清楚如何有效地返回数据。该函数看起来像

// 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);
  });

}

我尝试在函数中创建变量然后修改它

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

testVar仍然是'hello',尽管我付出了最大的努力。我已经完成了关于范围和承诺的一些阅读,但如果有一些我不理解的核心机制,我很乐意做更多。谢谢你的阅读!

2 个答案:

答案 0 :(得分:4)

由于请求的异步性,响应永远不会在您的调用代码中可用。你可以使用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);
  });

<script src="https://d3js.org/d3.v4.min.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:3)

您可以返回Promise并使用relatedArtists功能

&#13;
&#13;
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) {
      	reject(error);
      } else {
      	resolve(data.artists);
      }
    });
  });
}


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

在这种情况下,您无法将值分配给testVar,因为d3.json是异步方法,这意味着d3.json可以在代码执行后完成。