while (repoUrlLink != null && count < 90) {
var xmlHttp = new XMLHttpRequest();
xmlHttp.open('GET', repoUrlLink, false);
xmlHttp.setRequestHeader('Authorization', 'Bearer ' + userData.accessToken);
xmlHttp.onload = function () {
if (xmlHttp.status != 200) {
displayNoAccessMessage();
break;
}
var result = JSON.parse(xmlHttp.responseText);
if (result.length == 0) {
displayNoRecordsMessage();
break;
}
var header = xmlHttp.getResponseHeader('link');
if (header) {
//doing something
}
else
repoUrlLink = null;
$.each(result, function (index, eachData) {
// doing something with data
count++;
});
}
xmlHttp.send();
}
一旦显示错误,是否有更好的方法可以退出循环。中断语句不起作用。是否有任何回调可能有用?
答案 0 :(得分:0)
正如有人在评论中所说,你会想要使用递归。这是因为xmlHttp是一个异步操作。当您调用send
时,浏览器将发送请求,然后继续执行代码,因此在调用onload函数时,它不再有效以突破循环。另外,作为一个函数,onload
无法调用break,因为while循环甚至不在同一范围内。
var count = 0;
var doXmlHttpCall = function() {
var xmlHttp = new XMLHttpRequest();
// additional setup code here
xmlHttp.onload = function() {
var errorFound = false;
if (/* some error case */) {
errorFound = true;
}
// process request
if (count < 90 && !errorFound) {
doXmlHttpCall();
}
}
}
doXmlHttpCall();
答案 1 :(得分:0)
使用promises重构代码的一些想法。
执行一个请求的promisified XMLHttpRequest请求函数getRepLink
。它拒绝请求错误和HTTP错误(不是&#34; 200&#34;状态)。
一个promisifed getSetOfRecords
函数,用于获取单个响应,将其解析为JSON数据并提取链接头值。如果没有记录,它会拒绝。
一个promisified进程记录函数,它尝试处理集合中给定数量的记录。它满足处理的记录数量。如果某些记录已被处理,它会忽略无记录错误。
// XMLHttp request
function getRepoLink (repUrlLink) {
return new Promise( function (resolve, reject) {
var xmlHttp = new XMLHttpRequest();
xmlHttp.open('GET', repoUrlLink, false);
xmlHttp.setRequestHeader('Authorization', 'Bearer ' + userData.accessToken);
xmlHttp.onload = function () {
if( xmlHttp.status == 200) {
resolve( xmlHttp);
}
else {
reject( new Error("HTTP error " + xmlHttp.status));
}
};
xmlHttp.onerror = reject;
xmlHttp.send();
});
}
// get a set of records
const EndOfRecords = new Error( "End of Records");
function getSetOfRecords( repUrlLink) {
return getRepoLink( repUrlLink).then(
function( xmlHttp) {
var result = JSON.parse(xmlHttp.responseText);
if (result.length == 0) {
displayNoRecordsMessage();
throw EndOfRecords; // reject the returned promise
}
var header = xmlHttp.getResponseHeader('link');
return {result, header}; // fulfill the returned promise
}
);
}
// get up to `count` records and process them
function processRecords( repUrlLink, count) {
var processed = 0;
function processSomeMore() {
return getSetOfRecords().then( function ({result, header}) {
$.each(result, function (index, eachData) {
// do something with data
processed++;
});
if( header) {
//do something with header
if( processed < count)
return processSomeMore() // asynchronous "recursion"
}
else {
// do as required if no link header present.
}
return processed; // fulfill returned promise
},
function( error) {
if( error === EndOfRecords && processed > 0) {
return processed; // got some records
};
throw error; // reject returned promise
});
}
return processSomeMore();
}
// Start asynchronous operation
processRecords( repUrlLink, 90)
.then( processed => console.log( processed + " records processed"))
.catch( error => console.log( error));