xialin
xialin

Reputation: 7756

Calling Parse.Cloud.httpRequest inside another httpRequest

I'm trying to call an API to retrieve a list of data, this data will help me get image source. So for each data entry, I try to call the image url and do some image processing using Parse Image. The problem is, the inner httpRequest has never been triggered... I don't know what is the reason... As Parse.com is not that popular, I could hardly find any solution for such a case...

Here's my code:

Parse.Cloud.httpRequest({
        url: api_url,
        method: 'POST'
    }).then(function(data){
        data = JSON.parse(data.text);
        var entries = data.entries;
        for (var i = 0; i < 100; i++) {
            entry = entries[i][1];
            var image_url = composeImgURL(entry);
            Parse.Cloud.httpRequest({
                url: image_url,
                success: function(httpResponse){
                    var image = new Image();
                    image.setData(httpResponse.buffer);

                    var size = Math.min(image.width(), image.height());
                    if(size > 300){
                        var ratio = 300 / size.toFixed(2);
                        image.scale({
                            ratio: ratio.toFixed(2)
                        });
                    }
                    image.setFormat("JPEG");
                    var base64 = image.data().toString("base64");
                    var cropped = new Parse.File("thumbnail.jpg", { base64: base64 });
                    cropped.save();
                    entries[i][1]['url'] = cropped.url;
                },
                error: function(httpResponse){
                    console.log(httpResponse);
                }
            });
        }
        return entries;
    }).then(function(entries){
        response.success(entries);
    });

Upvotes: 3

Views: 2880

Answers (1)

ardrian
ardrian

Reputation: 1249

Your Current Code Your code will reach the return entries statement before any of your 100 http requests have completed. As soon as this occurs the line response.success(entries); will be called, and your cloud function will exit.

Parallel Promises For this situation, what you want to use are parallel promises. The docs are here:

https://parse.com/docs/js_guide#promises-parallel

There is a relevant question/answer on Parse answers here: https://www.parse.com/questions/parallel-promises-with-parsepromisewhen

Future Problems The above will work for simple functionality, however you are doing 2 more things inside your for loop which will require more time

  1. cropped.save(); you should wait for this function to return
  2. Cropping 100 images inside a cloud function probably won't work. A cloud function only runs for approximately 15 seconds. If crops take too long, some will occur and some won't. You could do something such as queuing images for cropping and performing those crops within a scheduled Job.

Upvotes: 4

Related Questions