如何使用break来基于xmlhttp响应代码的while循环?

时间:2017-07-28 22:50:31

标签: javascript asynchronous callback xmlhttprequest

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

一旦显示错误,是否有更好的方法可以退出循环。中断语句不起作用。是否有任何回调可能有用?

2 个答案:

答案 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));