简体   繁体   中英

Javascript: Break from loop

I want to keep checking a list until it finds an item that is available. For each item in the list it will make a post request to check if the item is available. I want to keep it asynchronous. Also note that i am using ajaxq function not ajax function, that is because i am using this queuing script http://code.google.com/p/jquery-ajaxq/ . So it won't be over before it's started sorta-thing. I'm sure thats not the problem though.

I need a way to break out of the loop once a item is available, so i can't just use a callback function because it won't be able to break out of the loop inside a function. So i thought incrementing a variable if its done and using a do-while loop would work, but it just freezes my browser like it's a never-ending loop.

Any suggestions on how do fix this or do it a better way would be great.

do {

    var d = 0;
    for(var i in list) {

        var item = list[i];

        $.ajaxq('queue', {
            type: 'POST',
            url: baseURL + '/ChangeItem/Check',
            data: {
                'newItem': item, 
                'purchaseItem': false
            },
            error: function(jqXHR, textStatus) {
                alert(textStatus);
            },
            dataType: 'text',
            success: function(data) {
                if(thisObject.isNotTaken(data)) {
                    d++;
                    thisObject.claimItem();
                }
            }
        });
    }

} while(d == 0);

You can use a recursive function:

function ChangeItem(list, index) {
        var item = list[index];

        $.ajaxq('queue', {
            type: 'POST',
            url: baseURL + '/ChangeItem/Check',
            data: { 'newItem': item, 'purchaseItem': false },
            error: function(jqXHR, textStatus) { alert(textStatus); },
            dataType: 'text',
            success: function(data) { 
                 if(thisObject.isNotTaken(data)) { thisObject.claimItem(); doWhateverYouWantNext(); } 
                 else ChangeItem(list, index+1);  
            }

        });
}

The fact that the requests will be queued only guarantees that they will be executed seuqentially, and that the first request will have finished before the second starts. It does not mean that your code to enqueue the second request will wait until the first request is finished. So ajaxq does not help you either way here. You'd have to fall back to a recursive function, that invokes itself from the AJAX callback.

Having said that, you'll notice this'll cause a series of requests to your server, and presumably a series of database lookups. You may find that it'd be a much neater approach to send teh entire list of items to the server, and return the first match from there.

Please try this:

var d = 0;
for(var i in list) {

    if(d == 0)
    {   
        var item = list[i];

        $.ajaxq('queue', {
            type: 'POST',
            url: baseURL + '/ChangeItem/Check',
            data: {
                'newItem': item, 
                'purchaseItem': false
            },
            error: function(jqXHR, textStatus) {
                alert(textStatus);
            },
            dataType: 'text',
            success: function(data) {
                if(thisObject.isNotTaken(data)) {
                    d++;
                    thisObject.claimItem();
                }
            }
        });

    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM