0

Here are my demo code:

doGet('../loaderDemo/1.lst');
doGet('../loaderDemo/2.lst');
doGet('../loaderDemo/3.lst');
doGet('../loaderDemo/4.lst');
doGet('../loaderDemo/5.lst');

function doGet(filename) {
    $.get(filename,function (data) {
        console.log(data + filename);
    });
}

the line "console.log(...)" may not be executed as the order of doGet(), the output contents is not as the order of 1.lst -> 2.lst -> 3.lst -> 4.lst -> 5.lst.

Actually the output order is just random in each execution.

how could I let it outputs in order?

Thanks for your help :-)

-------------Update-------------------

the ".lst" files are 3D models that I want to load. I just want to load the models in order so that I can render an animation properly. so which is the best solution in this case?

each ".lst" files includes the information of one frame. and in this demo,the outputs of "console.log()" must be in order as 1.lst -> 2.lst -> 3.lst -> 4.lst -> 5.lst so that I can handle rendering a frame animation.

HT XU
  • 137
  • 1
  • 3
  • 8
  • 1
    $.get is asynchronous – Jaromanda X Aug 11 '16 at 06:26
  • You can use recursive function to force async calls to run synchronously. – Samuel Toh Aug 11 '16 at 06:27
  • @JaromandaX – What could be the solution ? – Rayon Aug 11 '16 at 06:27
  • http://stackoverflow.com/q/133310/1005215 – Nehal J Wani Aug 11 '16 at 06:29
  • the solution depends on the actual "problem" you want to solve ... the order of console.log? or do you want to ensure the **completion** order of the gets? – Jaromanda X Aug 11 '16 at 06:32
  • the ".lst" files are 3D models that I want to load. I just want to load the models in order so that I can render an animation properly. so which is the best solution in this case? Thank you so much. @JaromandaX – HT XU Aug 11 '16 at 06:39
  • so, can you load the files in any order? or are there dependencies that require the files to be loaded in a particular order? – Jaromanda X Aug 11 '16 at 06:42
  • yes, the console.logs must be in order (see my solution for that) but that delays the loading of 2 until 1 has completely loaded, and 3 waits for 2, and 4 waits for 3 ... so there's only one download at a time. Is that a requirement? Or do you only need to process the results of the get in order, regardless of when the download finished? – Jaromanda X Aug 11 '16 at 06:49
  • @JaromandaX In this case, I just want to process the results of get in order – HT XU Aug 11 '16 at 06:54

2 Answers2

1

jQuery $.get returns a Promise (of sorts)

So, with minimal rewrite, you can do as follows

doGet('../loaderDemo/1.lst')
.then(function() {
    doGet('../loaderDemo/2.lst');
})
.then(function() {
    doGet('../loaderDemo/3.lst');
})
.then(function() {
    doGet('../loaderDemo/4.lst');
})
.then(function() {
    doGet('../loaderDemo/5.lst');
});

function doGet(filename) {
    // added return
    return $.get(filename,function (data) {
        console.log(data + filename);
    });
}

If, however, the order of download completion is not important, but order of "processing" is - you can use jQuery.when to "wait" for all the downloads to complete, then process the results in the order required

$.when(doGet('../loaderDemo/1.lst'),
    doGet('../loaderDemo/2.lst'),
    doGet('../loaderDemo/3.lst'),
    doGet('../loaderDemo/4.lst'),
    doGet('../loaderDemo/5.lst')
)
.done(function(v1, v2, v3, v4, v5) {
    [].forEach.call(arguments, function(arg) {}
        console.log(arg.data, arg.filename);
    })
});

function doGet(filename) {
    return $.get(filename)
    .then(function(data) {
        // need this so we can access the filename and the data for each result
        return {
            data: data,
            filename: filename
        };
    });
}
Jaromanda X
  • 53,868
  • 5
  • 73
  • 87
  • 1
    But using this approach, you are delaying the `get-call` of next request... Any approach for making requests in parallel but getting response in order ? – Rayon Aug 11 '16 at 06:38
  • Yes, that is true - depends on which problem he wants to fix - let me add another solution – Jaromanda X Aug 11 '16 at 06:38
0

Welcome to the world of asynchronous programming. The best way to handle this is to call all 5 asynch functions at the same time, but delay the execution of the console log statements until they are all completed, and then run them in order.

(This is, of course, assuming that it's really important to run them in the same order all the time. An even better solution might be refactoring your code so that it doesn't matter which one completes first)

Here's an example for your problem.

Mostly, this is way faster than any of the sequential solutions posted because it's going to run 5 calls at the same time instead of 5 calls one after the other.

return $.when(
    doGet('../loaderDemo/1.lst'),
    doGet('../loaderDemo/2.lst'),
    doGet('../loaderDemo/3.lst'),
    doGet('../loaderDemo/4.lst'),
    doGet('../loaderDemo/5.lst'),
).done( function(res1, res2, res3, res4, res5 ) {
  console.log(res1),
  console.log(res2),
  console.log(res3),
  console.log(res4),
  console.log(res5),
});

(My previous edit used $q, but it turns out that jquery has a built-in thing that works almost the same)

Erik
  • 3,598
  • 14
  • 29