Patrick Haugen
Patrick Haugen

Reputation: 1

Vue JS Promise Sequential vs Parallel

I have working code in VueJS however need a certain block to run sequentially:

  return Promise.all(this.vm.multipleActions.run.map(function (testRun) {
    return self.initiateTest(testRun);
  }))

Currently it seems this runs in parallel - so in initiateTest() I insert records into a DB however parallel gets me random ordering instead of the testRuns in order (which I'd like to preserve).

I can observe the AJAX calls in initiateTest() made randomly due to the parallel nature.

Upvotes: 0

Views: 1246

Answers (2)

Jaromanda X
Jaromanda X

Reputation: 1

If you want to return the results of self.initiateTest(testRun) in the returned promise like your code does with Promise.all, you can use array reduce function like so

return this.vm.multipleActions.run.reduce((promise, testRun) =>
    promise.then(results => 
        self.initiateTest(testRun).then(result => {
            results.push(result);
            return results;
        })
    ), Promise.resolve([]) // initial promise to chain to
);

Note: if using arrow functions, the self.initiateTest could possibly be this.initiateTest - though, it's not clear what self is in your code

The returned promise will resolve to an array of (resolved) results returned by self.initiateTest(testRun)

the non ES2015+ version of the above code is

return this.vm.multipleActions.run.reduce(function (promise, testRun) {
    return promise.then(function (results) {
        return self.initiateTest(testRun).then(function (result) {
            results.push(result);
            return results;
        });
    });
}, Promise.resolve([]));

Upvotes: 1

James
James

Reputation: 106

To get the them to run sequentially, you need to call initiateTest once the previous test has completed.

var promise = Promise.resolve();
this.vm.multipleActions.run.forEach(function (testRun) {
    promise = promise.then(function() {
        return self.initiateTest(testRun);
    });
})
return promise;

This code will create an initial promise that is resolved immediately. Each test run is attached to the promise's then handler, so they only execute once the previous promise has been resolved.

Or to shorten it even further, you can use reduce:

return this.vm.multipleActions.run.reduce(function (promise, testRun) {
    return promise.then(function() {
        return self.initiateTest(testRun);
    });
}, Promise.resolve())

Upvotes: 0

Related Questions