0

I am using jQuery v2.1.4, I have the following function which for each object in evt.data.files(the number of element in the array will vary) needs to make a request to a server.

The problem I am facing with this script is that for each element in evt.data.files an asynchronous request is made, instead I need:

  • execute each request in sequence (if possible with jQuery)
  • call a single method when all the request are successfully returned.

Could you please suggest me a solution with an example? Thanks.

options.onInit = function (finder) {
    finder.on('files:choose', function (evt) {
        // files is an array of n object
        evt.data.files.forEach(function (file) {
            // req is an jquery deferred object
            var req = finder.request('command:send', {
                name: 'ImageInfo',
                folder: file.get('folder'),
                params: { fileName: file.get('name') }
            }).done(function (response) {
                if (response.error) {
                    return;
                }

            });
        });
    });
}.bind(this);
9
  • You can chain your .done events. Commented Feb 10, 2016 at 12:33
  • 1
    Switch to a promise-based code model. You can then use .then() for sequence and $.when() for parallel operations (like "all done"). Commented Feb 10, 2016 at 12:34
  • Thanks for commenting, I made an edit, I understand your point but the number of element in evt.data.files is variable Commented Feb 10, 2016 at 12:34
  • @GoneCodingGoodbye how to pass to $.when() the promises (dynamically create in the forEach), thanks for commenting. Commented Feb 10, 2016 at 12:38
  • Maybe you can try something like this: http://stackoverflow.com/a/35056741/5850827 Commented Feb 10, 2016 at 12:41

1 Answer 1

2

I realise I misread the question first time. You only need to run the requests sequentially and await the last one:

Use promise = promise.then(newPromise) to chain promises sequentially:

e.g.

options.onInit = function (finder) {
    finder.on('files:choose', function (evt) {
        var promise = $.when(); // start with a resolved promise

        // files is an array of n object
        evt.data.files.forEach(function (file) {
            promise = promise.then(function(){
               return finder.request('command:send', {
                  name: 'ImageInfo',
                  folder: file.get('folder'),
                  params: { fileName: file.get('name') }
               });
            });
        });
        promise.then(function(){
            alert("Last one done");
        });
    });
}.bind(this);

The key feature here is to return the promise inside an anonymous function in each then call. This defers the execution until the previous promise resolves, but still chains the promises.

Sign up to request clarification or add additional context in comments.

1 Comment

Please guys, add a comment when down-voting. By the way, this answer solved my issue. Thanks for your time on this!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.