Promises in Series are not getting executed in seq

2019-09-09 16:29发布

问题:

I have written the code based on the Parse example provided in Parse.com to execute the promises in Series.

But, seems like sequential processing is not working fine.

The below code calls a cloud function namely 'sampleCloudFuction' multiple times but in sequential order through Series of Promises.

After executing the loop, app will make a call to another js function which will load the remaining items (excluding the processed items).

This is the Loop which make multiple calls to the cloud function:

var seriesPromise = new Parse.Promise.as();

 $.each(items, function (i) {
                ..
                ..

                count++;
                if (count >= 25 || (i + 1) >= selectedItemsLength) {

                    .. ..

//Series Promise: The code to be executed in sequence being placed within the 
//then() the existing promise

                    seriesPromise = seriesPromise.then(function () {
                        Parse.Cloud.run('sampleCloudFuction', itemsArray, function () {
                            console.log("success callback in JS");
                            var tempPromise = Parse.Promise.as();
                            return tempPromise;


                        }, function (error) {
                            alert("Error " + error.code + "::");
                            console.log("error callback in JS")
                        });
                    });

                    count = 0;


                }
            });

..
..


seriesPromise.then(function () {
                //Fetch the approval state of the disabled button
                alert("load remaining items");

            });

The below function is to be called after executing the loop. But, this is being called well in before receiving the callbacks for all earlier requests.

seriesPromise.then(function () {
            //Fetch the approval state of the disabled button
            alert("load remaining items");

        });

回答1:

Parse.Cloud.run('sampleCloudFuction', itemsArray, function () {
    console.log("success callback in JS");
    var tempPromise = Parse.Promise.as();
    return tempPromise;
})

That doesn't work. You cannot return from a callback - the value will just vanish.

However, the docs state that

every asynchronous method in the Parse JavaScript SDK returns a Promise

- you don't even need to try to construct it on your own!

So, why is the sequential processing not working correctly? Because it requires that the then callback does return the value of the next step - which can be an asynchronous, not yet resolved promise. Then, the new seriesPromise will wait for that step before executing the next.

Yet you were not returning anything from that callback - so the then just resolved the seriesPromise immediately with undefined. Return the promise that .run() yields:

var seriesPromise = new Parse.Promise.as();
$.each(items, function (i) {
    …
    // Series Promise: The code to be executed in sequence being placed within the 
    // then() the existing promise
    seriesPromise = seriesPromise.then(function() {
       return Parse.Cloud.run('sampleCloudFuction', itemsArray);
//     ^^^^^^
    });
    …
});
seriesPromise.then(function () {
    //Fetch the approval state of the disabled button
    alert("load remaining items");
}, function (error) {
    alert("Error " + error.code + "::");
    console.log("error callback in JS");
});


回答2:

var seriesPromise = new Parse.Promise.as();

 $.each(items, function (i) {
                ..
                ..

                count++;
                if (count >= 25 || (i + 1) >= selectedItemsLength) {

                    .. ..

                // I don't know where you got the understand wrapping code in 
                // Parse.Promise.as() it will executed in series. 

                // from the docs:
                // Parse.Promise.as()
                // Returns a new promise that is resolved with a given value.

                // in fact the following line executed right away and this foreach 
                // function for this item return immediately.
                    seriesPromise = seriesPromise.then(function () {
                        Parse.Cloud.run('sampleCloudFuction', itemsArray, function () {
                            console.log("success callback in JS");
                            var tempPromise = Parse.Promise.as();
                            return tempPromise;


                        }, function (error) {
                            alert("Error " + error.code + "::");
                            console.log("error callback in JS")
                        });
                    });

                    count = 0;


                }
            });

Unfortunately I don't really understand what you trying to do. if your code is too long you can put a jsfiddle.