-1

I have an array of objects, each object has some properties, each property contains an url of an image.

I have more arrays, and I want download all these images, so I use fetch() promise. Promise.all() accepts an array of promises, so I run Promise.all() for each property, since I don't want to have an array with all the promise for all the properties.

But.. do I have to write all of them manually? I know I can't use for loops. Or do I have to use recursion (if it is possible in this case), each time calling a function from the inside with a new array?

EDIT: the use case

//first I build arrays for promises
// var results is an array of arrays that contain objects -> results[i]Items[k].property

var items_offline_img = [];

for (var i = results.length - 1; i >= 0; i--) {

    for (var k = results[i].Items.length - 1; k >= 0; k--) {
        var images = new Object();
        images.Src = results[i].Items[k].Src;
        images.Src2 = results[i].Items[k].Src2;
        images.Src3 = results[i].Items[k].Src3;

        items_offline_img.push(images);
    }
}

// Now I have to make Promise.all() for every items_offline_img[i].Src, and then for Src2 and so on.


// Promise block


var promises = [];

for (var i = items_offline_img.length - 1; i >= 0; i--) {
    promises.push(fetch(items_offline_img[i].Src));

}

Promise
    .all(promises)
    .then(function(response) {
        var blobs = [];
        for (var i = response.length - 1; i >= 0; i--) {
            var blb = response[i].blob();
            blobs.push(blb);
        }
        return Promise.all(blobs);
    })
    .then(function(blobsPromise) {
        var urlCreator = window.URL || window.webkitURL;
        for (var i = blobsPromise.length - 1; i >= 0; i--) {
            lcl_images[i].value = urlCreator.createObjectURL(blobsPromise[i]);
        }

        setItem();

    })
    .catch(function(error) {
        console.log(error);
    });

And now have I to write manually additional Promise blocks for Src2, Src3, and so on?

Ok I could fetch all images with only 1 array, but I have to turn images in blobs and store them with localForage.

By this way, with only 1 array, in .then(function(blobsPromise) I don't know to which item the image referts to.

Workaround: I could replicate the array structure with images only. Like

replicate_Items[i].Src 
replicate_Items[i].Src2
repliacte_Items[i].Src3

where replicate_Items[i].Src, replicate_Items[i].Src2, replicate_Items[i].Src3 in blobsPromise[i], blobsPromise[i+1], blobsPromise[i+2]

.then(function(blobsPromise) {

    var urlCreator = window.URL || window.webkitURL;
    var images_num = Object.keys(replicate_Items[0]).length;
    var current_image_num = 0;
    var k = 0; // replicate_Items[k]
    var objectURL;

    for (var i = blobsPromise.length - 1; i >= 0; i--) {

        objectURL = urlCreator.createObjectURL(blobsPromise[i]);

        if (current_image_num == 1)
            replicate_Items[k].Src = objectURL;
        if (current_image_num == 2)
            replicate_Items[k].Src2 = objectURL;
        if (current_image_num == 3)
            replicate_Items[k].Src3 = objectURL;

        current_image_num++;
        if (current_image_num = images_num) {
            current_image_num = 1;
            k++;
            images_num = Object.keys(replicate_Items[k]).length;
        }
    }

    setItem();

})

What do you think?

FrancescoN
  • 2,146
  • 12
  • 34
  • 45
  • See http://stackoverflow.com/questions/38034574/multiple-sequential-fetch-promise/ – guest271314 Jun 27 '16 at 02:11
  • Can you share executable demo/snippet or [JSFiddle](https://jsfiddle.net/) ? [_Create a Minimal, Complete, and Verifiable example_](http://stackoverflow.com/help/mcve) – Rayon Jun 27 '16 at 02:21
  • 1
    *"I know I can't use for loops"* ... yes you can if use a closure also. Why is this question any different than the last one you asked about this? without some sort of data sample and more detail the question is a bit abstract – charlietfl Jun 27 '16 at 02:23
  • 1
    Too theoretical and therefore not clear exactly what you're trying to do. Please post the code you have so far. I don't see any reason from your description why you can't start everything downloading at once and just use `Promise.all()` for all the promises. I don't see any requirement to sequence things in your description. – jfriend00 Jun 27 '16 at 02:41
  • 1
    Yes, if you cannot use loops then you have to write it out by hand, but I don't think that's the case. Please post your code, how you would write it out (abbreviated if necessary) and why you think that you couldn't use for loops. – Bergi Jun 27 '16 at 03:03
  • You know how to enumerate objects, and how bracket notation works? – Bergi Jun 27 '16 at 08:58
  • Let me know if it all has a meaning now. Doing `Promise.all()` with all images, from different items, in one array it's a problem because I have to keep a relation to which item an image refers to. Let me know if the workaround could be a good solution @Bergi brackets notation? of course I'm using objects. I've seen enumerate some time ago, not in JS – FrancescoN Jun 27 '16 at 10:40

1 Answers1

0

One can use a property accessor to iterate through a list of Src properties to create a flat promise list.

// Promise block

var jList = ['Src','Src1','Src2'];
var promises = [];

for (var j=0; j < jList.length; j++) {
    var jSrc = jList[j];
    for (var i = items_offline_img.length - 1; i >= 0; i--) {
         promises.push(fetch(items_offline_img[i][jSrc]));
    };
};

The above example uses nested for loops to create a flat list of image promises. Notice the use of a property accessor to iterate through a list of source properties.

georgeawg
  • 48,608
  • 13
  • 72
  • 95