干净的方式使后续AJAX调用基于数据的API
Clean way to make Subsequent AJAX Calls to API based on Data
所以我有一个概念上的问题,关于基于返回的数据对API进行后续AJAX调用的最干净的方法。
一个简单的例子:
包含调用的函数应该是这样的:
function makeCall(headers, min, max) {
$.ajax({
headers: headers,
url: "https://coolapi.com/data?begIndex" + min + "&endIndex=" + max + "&begTimestamp=1404198000000&endTimestamp=1409554800000",
type: "GET",
dataType: 'JSON'
});
}
makeCall(headers, 0, 20);
beg/end索引(min/max),决定我将在数组中返回的数据量。API将只返回数组中最多20个项目,但它也将返回一个COUNT,表示该数组中总共存在多少个项目。返回的数据示例如下:
{
count = 133;
result = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19];
}
所以我的下一个调用是:
makeCall(headers, 20, 40);
等等,直到我从数组中得到所有133项。
问题是……在获得并存储数组中的所有133项之前,继续进行后续调用的最干净的方法是什么?考虑到计数可以是任意数,很难想象我如何做到这一点。我正在考虑在"成功"函数中嵌套更多的ajax调用,但如果我返回一个像300这样的数字,它就无法扩展。
有人对如何进行有什么建议吗?
提前感谢!
编辑:因此,根据评论中的建议,我试图使调用递归-但它似乎没有按预期工作:
var theData = [];
var minCounter=0;
var maxCounter= minCounter + 20;
function makeCall(headers, min, max) {
$.ajax({
headers: headers,
url: "https://coolapi.com/data?begIndex" + min + "&endIndex=" + max + "&begTimestamp=1404198000000&endTimestamp=1409554800000",
type: "GET",
dataType: 'JSON',
success: function (data) {
theData.push(data.result);
newMin = minCounter + 20;
if (data.count >= theData.length ) {
makeCall(headers, newMin, maxCounter);
}
}
});
}
makeCall(headers, minCounter, maxCounter);
如何正确地增加变量以及设置标志?
第二个编辑:
下面的方法使用了第二个评论的建议,但是这里也有一些问题…
function doAjax(headers, min, dObject) {
var max = min + 20;
$.ajax({
headers: headers,
url: "https://coolapi.com/data?begIndex" + min + "&endIndex=" + max + "&begTimestamp=1404198000000&endTimestamp=1409554800000",
type: "GET",
dataType: 'JSON',
success: function (data) {
results.push(data);
window.count = data.count;
dObject.resolve();
}
});
}
// array that will contain all deferred objects
var deferreds = [];
// array that will contain all results
var results = [];
// make the ajax calls
for (var i = 20; i < 133 ; i+= 20) {
var dObject = new $.Deferred();
deferreds.push(dObject);
doAjax(headers, i, dObject);
}
// check if all ajax calls have finished
$.when.apply($, deferreds).done(function() {
console.log(results);
});
var dObject = new $.Deferred();
doAjax(headers,0, dObject);
首先,数据没有按顺序压入数组。似乎没有办法解决这个问题。很奇怪的是,在for循环中,我必须设置数值才能让它工作。试图将其存储在变量中似乎并不奏效……建议吗?
下面是基于您开始使用的代码的工作实现。注释代码以帮助您理解正在发生的事情:
// Change these constants to suit your purposes.
var API_URL = 'https://coolapi.com/data';
var HEADERS = {};
var API_RESULTS_PER_REQUEST = 20;
var MAX_API_CALLS = 20;
// Count API calls to trigger MAX_API_CALLS safety lock.
var apiCalls = 0;
// Function we'll call to get all our data (see bottom).
function collectApiData(begTimestamp, endTimestamp) {
var dataReady = jQuery.Deferred();
var params = {
'begTimestamp': begTimestamp,
'endTimestamp': endTimestamp
};
var datasetsCollected = requestDatasets(params);
jQuery.when(datasetsCollected).then(function(data) {
dataReady.resolve(data);
});
return dataReady;
}
// Makes individual AJAX call to API
function callApi(params, headers) {
var $request = jQuery.ajax({
url: API_URL,
headers: headers,
data: params,
type: 'GET',
dataType: 'JSON'
});
return $request;
}
// Recursive function that makes API calls until data is collected, there is an
// error, or MAX_API_CALLS limit is hit.
function requestDatasets(params, resultsReady, resultsFetched) {
resultsReady = ( resultsReady !== undefined ) ? resultsReady : jQuery.Deferred();
resultsFetched = ( resultsFetched !== undefined ) ? resultsFetched : [];
// Trigger safety to avoid API abuse
if ( apiCalls >= MAX_API_CALLS ) {
console.error('Exceeded max API calls:', MAX_API_CALLS);
resultsReady.resolve(resultsFetched);
}
// Set index data
params.begIndex = resultsFetched.length;
params.endIndex = resultsFetched.length + API_RESULTS_PER_REQUEST;
// Request dataset from API
var apiRequest = callApi(params, HEADERS);
apiCalls += 1;
// Callback once API request has completed and data is ready
jQuery.when(apiRequest).done(function(data) {
var apiResultCount = data.count;
resultsFetched = resultsFetched.concat(data.result);
console.debug('Fetched', resultsFetched.length, 'of', apiResultCount, 'API results');
if ( apiResultCount > resultsFetched.length ) {
console.debug('Making another API call');
requestDatasets(params, resultsReady, resultsFetched);
}
else {
console.debug('Results all fetched!');
resultsReady.resolve(resultsFetched);
}
});
jQuery.when(apiRequest).fail(function(data) {
console.error('API error: returning current results.');
resultsReady.resolve(resultsFetched);
});
return resultsReady;
}
// Run script
var dataReady = collectApiData('1404198000000', '1409554800000');
jQuery.when(dataReady).then(function(data) {
console.log(data);
});
这是一个使用httpbin.org模拟API的工作小提琴:
http://jsfiddle.net/klenwell/mfhLxun2/相关文章:
- 使用Angular获取数据API调用时出错
- Facebook网络数据API和D3.JS
- D3:“bubble.nodes”未将正确的图形数据应用于数据集
- 将动态样式应用于数据表行
- 陷入Json,无法使用敲除映射控件将Bindings应用于数据
- 使用播放按钮和/或元数据API(Spotify)进行现场演示
- 有没有办法使用谷歌地图javascript api突出显示一个国家,类似于嵌入api
- YouTube 数据 API 说,当闲置几个小时时,我已经超过了每日使用限制
- 通过传递类别从维基数据 api 填充自动完成
- YouTube 数据 API:检查视频是否启用了分级
- 为什么其中一个侦听器适用于媒体 API 事件,而另一个则不适用于媒体 API 事件
- 无法在 MVC 中使用 jquery/js 将 json 数据(API 结果)绑定到下拉列表
- 在 JavaScript 中处理 YouTube 数据 API 中的错误
- Youtube数据API-未压缩类型错误:无法读取属性'搜索'的未定义
- 如何在HTML5-音频/Mozilla音频数据API中进行平移
- D3js如何获得悬停时显示的特定于数据的工具提示
- YouTube数据API v3使用Javascript
- 如何检测浏览器支持HTML5微数据API
- Youtube数据API和谷歌云端点
- d3.js中单个节点中的复杂符号,其中符号依赖于数据