1

I implemented this:

It's possible to 'GET' multiple XML files with javascript?

However, my problem is more complex because I have a much larger number of xml files (40).

I made the promises array like so:

var promises = [ xmlPromise('data/sequence/xml/0.xml'),
                 xmlPromise('data/sequence/xml/1.xml'),
                 xmlPromise('data/sequence/xml/2.xml'),
                 xmlPromise('data/sequence/xml/3.xml'),
                 xmlPromise('data/sequence/xml/4.xml'),

etc.

When I look at the data in the xml files in the console log for:

for (i = 0; i < 40; i++) {
    console.log(responses[i].value);

I notice that the files are not in the same order in the responses array as they were added to the promises array? Instead, the order seems to be completely random? It is important that the order of both the promises and responses arrays are the same. Because of what I want to do next with the data. Why is it not in the same order? Please help somebody.

== Additional ==

Here is the full code:

function xmlPromise(name) {
    return Q.promise(function (resolve, reject, notify) {
        $.ajax({
            type: "GET",
            dataType: "xml",
            async: true,
            url: name,
            contentType: "text/xml; charset=UTF-8"
        })        
       .done(function (data) {
           resolve(data);
        }).fail(function () {
            reject();
        });
    });
};

var promises = [ xmlPromise('data/sequence/xml/0.xml'),
                 xmlPromise('data/sequence/xml/1.xml'),
                 xmlPromise('data/sequence/xml/2.xml'),
                 xmlPromise('data/sequence/xml/3.xml'),
                 xmlPromise('data/sequence/xml/4.xml'),
                 xmlPromise('data/sequence/xml/5.xml'),
                 xmlPromise('data/sequence/xml/6.xml'),
                 xmlPromise('data/sequence/xml/7.xml'),
                 xmlPromise('data/sequence/xml/8.xml'),
                 xmlPromise('data/sequence/xml/9.xml'),
                 xmlPromise('data/sequence/xml/10.xml'),
                 xmlPromise('data/sequence/xml/11.xml'),
                 xmlPromise('data/sequence/xml/12.xml'),
                 xmlPromise('data/sequence/xml/13.xml'),
                 xmlPromise('data/sequence/xml/14.xml'),
                 xmlPromise('data/sequence/xml/15.xml'),
                 xmlPromise('data/sequence/xml/16.xml'),
                 xmlPromise('data/sequence/xml/17.xml'),
                 xmlPromise('data/sequence/xml/18.xml'),
                 xmlPromise('data/sequence/xml/19.xml'),
                 xmlPromise('data/sequence/xml/20.xml'),
                 xmlPromise('data/sequence/xml/21.xml'),
                 xmlPromise('data/sequence/xml/22.xml'),
                 xmlPromise('data/sequence/xml/23.xml'),
                 xmlPromise('data/sequence/xml/24.xml'),
                 xmlPromise('data/sequence/xml/25.xml'),
                 xmlPromise('data/sequence/xml/26.xml'),
                 xmlPromise('data/sequence/xml/27.xml'),
                 xmlPromise('data/sequence/xml/28.xml'),
                 xmlPromise('data/sequence/xml/29.xml'),
                 xmlPromise('data/sequence/xml/30.xml'),
                 xmlPromise('data/sequence/xml/31.xml'),
                 xmlPromise('data/sequence/xml/32.xml'),
                 xmlPromise('data/sequence/xml/33.xml'),
                 xmlPromise('data/sequence/xml/34.xml'),
                 xmlPromise('data/sequence/xml/35.xml'),
                 xmlPromise('data/sequence/xml/36.xml'),
                 xmlPromise('data/sequence/xml/37.xml'),
                 xmlPromise('data/sequence/xml/38.xml'),
                 xmlPromise('data/sequence/xml/39.xml') ];

var results = [];

Q.allSettled(promises).then(function(responses) {
    for (i = 0; i < 40; i++) {
        console.log(responses[i].value);
        results.push(responses[i].value);
    }
});
Steve
  • 37
  • 6
  • 1
    Promise.all will produce an array of results in correspondence to the array of promises. Please post the code that creates the promise – danh Jun 14 '18 at 02:58
  • Thank you for replying. I updated the code. – Steve Jun 14 '18 at 04:09

1 Answers1

1

It's surprising that the OP code doesn't result in a correspondence between the params to the deferred operation and the result, but we can force the issue this way...

let objects = [ { name:'data/sequence/xml/0.xml', data:null },
                { name:'data/sequence/xml/1.xml', data:null }, // ...


function xmlGetter(object) {
    return Q.promise(function (resolve, reject, notify) {
        $.ajax({
            type: "GET",
            dataType: "xml",
            async: true,
            url: object.name,                       // <-- changed
            contentType: "text/xml; charset=UTF-8"
        })        
       .done(function (data) {
           object.data = data.value;                // <-- changed
           resolve(object);                         // <-- changed
        }).fail(function () {
            reject();
        });
    });
};

let promises = xmlObjects.map(function(object) {
    return xmlGetter(object);
});

Q.allSettled(promises).then(function() {
    for (i = 0; i < objects.length; i++) {
        console.log('file ' + i + ' data ' + object.data);
    }
});

Notice that the code ignores the allSettled result (which really should be the same collection of objects, ordered the same way) because the original name/data collection remains in the execution context.

This way, there's no chance of disassociating the data with the params, no matter how the code chooses to use promises or how the aggregate promise implementation works. Another benefit is that the code can interrogate the objects array while execution proceeds to, for example, measure progress by counting the nulls in the data property.

danh
  • 62,181
  • 10
  • 95
  • 136
  • Yes. This works, thank you! Strangely, having shut down my PC last night and used it again this morning, my original implementation works as well?! Maybe a caching issue?! Anyways, thank you very much for this response, greatly appreciated man. I hope if anyone else gets a similar issue in the future they can see your response and rectify it! – Steve Jun 15 '18 at 04:40