对于我的网站,我使用的是一个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调用都在单独的函数中,但我在这里简化它以减少示例中的代码量。
答案 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);
});
}