将数据加载到需要多次调用API的网页

时间:2017-04-20 17:26:51

标签: javascript api

对于我的网站,我使用的是一个API,我需要从中加载几个变量。每个变量都依赖于前一个调用的返回值(我使用从调用1返回的变量来调用2等)。

实施例: 假设我需要进行5次不同的API调用来收集我的所有数据,每次调用都取决于前一次调用的返回值。然后在我的情况下,我这样做。我将回调函数传递给第一个加载数据的函数。然后该函数将进行第一次API调用。当该调用完成时,它将把回调函数传递给进行第二次API调用的下一个函数,依此类推。当最后一次API调用完成后,调用回调函数,然后我知道所有数据都已加载。在代码中它看起来像这样(我在我的应用程序中使用Trello API,所以我将在下面的示例中使用它):

function loadData(cb){
  //Make the first API call
  Trello.get('/member/me/boards', function(boards){
    myBoards = boards;
    for(var i = 0; i < boards.length; i++){
      //Make the second API call
      Trello.get('/boards/' + board[i].id + '/lists', function(lists){
        board[i].lists = lists;
        //Then make the third and fourth and so on 
        .....
        //When all calls are made call the callback function
        cb();
      });
  });
}

正如您所看到的,回调函数将在很长一段时间内传递到callstack中。我想知道是否有更好的方法来加载数据并存储它(截至目前我只是将所有内容存储在一个大型数组中)。从API加载大量数据的最佳实践是什么?

P.S。在我的原始代码中,每个API调用都在单独的函数中,但我在这里简化它以减少示例中的代码量。

3 个答案:

答案 0 :(得分:1)

我不知道这是否适合你,但使用 TypeScript 可以更轻松地解决这类JavaScript问题:

async function loadData() {
    const boards = await Trello.get('/member/me/boards');
    return boards.map(async (board) => {
        const lists = await Trello.get('/boards/' + board.id + '/lists');
        const something = await Trello.get('/...');
        const somethingElse = await Trello.get('/...');
        // ...more calls
        return {
            ...board,
            lists: lists,
            something: something,
            somethingElse: somethingElse
            // ... more attributes
        };
    });
}

loadData().then((data) => console.log(data));

答案 1 :(得分:1)

如果不完全了解您的问题,这可能不是一个有效的解决方案,但快速浏览trello api docs会显示您可以进行的批量调用,以避免在每个级别进行循环。对这些进行批处理可以使每个级别的API调用更少,并且被认为是最佳实践:

function loadData(cb){
  //Make the first API call
  Trello.get('/member/me/boards', function(boards){
    myBoards = boards;
    var boardAPIs = [];
    var boardResponses = [];
    for(var i = 0; i < boards.length; i++){
      boardAPIs.push('/boards/' + board[i].id + '/lists');
      //max of 10 at a time per documentation
      if (boardAPIs.length == 10 || i >= (boards.length - 1)) {
          //Make the second level API call
         Trello.get('/batch/?urls=' + boardAPIs.join(','), function(boards){
            // collect response information on all boards, then continue with third request
            boardResponses.push(...);

            if (i >= (boards.length - 1)) {
                // all board requests have been made, continue execution at third level
                // if this were the last level of calls, you could call cb() here
                for(var j = 0; i < boardResponses.length; i++){
                    // loop inside responses to get individual board responses, build up next set of batch requests
                }
            }
         });
         boardAPIs= [];
      }
     });


  });
}

有一点需要注意:文档中提到您一次只能批量处理10个请求,因此我在其中添加了一些代码来检查。

This post提供了有关如何使用批处理服务的更多信息:

  

这意味着你只得到一个回复​​,看起来有点   与正常反应不同。响应是一个对象数组    - 但不是您可能期望的正常响应对象。代替,   它是一个具有单个属性的对象,其名称设置为HTTP   请求的响应代码。

答案 2 :(得分:0)

您可以专注于深度优先方法,以便第一批数据快速到达客户端:

function loadData(showChunk){
//Make the first API call
Trello.get('/member/me/boards', function(boards){
   myBoards = boards;
   (function getboard(i){
        //Make the second API call
        Trello.get('/boards/' + board[i].id + '/lists', function(lists){
             board[i].lists = lists;
        //Then make the third and fourth and so on 
        .....
        //When all calls are made for the first board call the callback function, and also continue with the next board
        showChunk();
        if(i+1<boards.length) setTimeout(getboard, 1, i+1);
     });
    })(0);
 });
}