0

Rookie question. It could be a possible duplicate, but I can't wrap my head around how to restructure the code. How should I structure the below code so that the console would print the following:

Here1 Here2 Here1 Here2 Here1 Here2

Now it goes:

Here1 Here1 Here1 Here2 Here2 Here2

Thanks for your help.

var record;

for ( i = 0; i < 3; i++ ) {
    sendRequest(selectTestsToRun('something1'), 'someTest1');
}

this.someTest1 = function(resObj, testToRun){
    console.log('Here1');
    record = resObj.value;
    sendRequest(selectTestsToRun('something2'), 'someTest2');
};

this.someTest2  = function(resObj, testToRun){
    console.log('Here2');
};

function selectTestsToRun(toDo){
    var data;

    switch( toDo) {
        case 'something1':
            data = 'postMessage';
            break;

        case 'something2':
            data = 'postMessage'+record;
            break;
    }

    return data;
}

function sendRequest(data , toDo ){

    GM_xmlhttpRequest({
        method: 'POST',
        url:  url,
        data: data,
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        onload: function(response) {
            var resObj = JSON.parse(response);
            this[toDo](resObj,toDo);
        }
    });

}
tadalendas
  • 1,461
  • 3
  • 16
  • 37

2 Answers2

1

You don't want a for loop at all. Instead, you want someTest2 to kick off the next iteration of the "loop":

var i = 0;
next();

function next() {
    if (i < 3) {
        sendRequest(selectTestsToRun('something1'), 'someTest1');
        ++i;
    }
}

this.someTest2  = function(resObj, testToRun){
    console.log('Here2');
    next();                                          // <==== Note
};

In the above, I've baked that into someTest2, but you can of course pass a callback around to decouple the loop from someTest2.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
0

You have to remember that AJAX calls happen asynchronously while the loop executes synchronously.

The loop calls test1 back to back, while the AJAX request take atleast 300ms to make a trip to and from the server. This most certainly will happen long after the loop has finished.

You need to use a callback (or promise) to call the next function. You can place the logic that determines which one to call next in the call back. Here is an example using jQuery for the Ajax communication.

I went old school and used a counter that is only incremented by the first calling function. When the counter reaches your limit, it acts like a switch and stops the viscous cycle.

You can see it work here:https://jsbin.com/wohife/

$(document).ready(function() {

    var counter = 0;


    function test1() {
        if (counter < 3) {
            sendRequest(1);
            console.log('here 1');
        }

        counter++;
    }

    function test2() {
        sendRequest(2);
        console.log('here 2');
    }

    function sendRequest(requesterId) {
        $.ajax({
            url: 'https://jsbin.com/sohefe/1.json',
            type: 'GET'
        })
        .success(function(data, status, req) {

            if (requesterId === 1) {
                test2();
            }
            else {
                test1();
            }

        });
    }

    test1();
});
Ron Sims II
  • 566
  • 5
  • 10