apex.server.process is the APEX method for calling a server side application process from JavaScript. It's easy to use and just requires you to specify the process name and some page items and/or standalone arguments. A success callback can be defined in order to perform some processing once the request has completed successfully.

apex.server.process(
    'My Process',
    {x01: myArgument},
    {
        type: 'POST',
        success: function(data) {
           console.log(data)
        }
    }
)

Interestingly, there is another way to handle a successful request by using jQuery's promise functionality.

https://api.jquery.com/category/deferred-object/

apex.server.process is really just a wrapper for the jQuery $.ajax function and therefore returns a jqXHR object that implements the promise interface.

This means that instead of defining a success callback function, we can take the object returned by the call to apex.server.process and attach a handler to it via the .done method.

apex.server.process(
    'My Process',
    {x01: myArgument},
    {type: 'POST'}
).done(function(data) {
    console.log(data);
});

Now for the good bit. What if we need to execute multiple requests in parallel and only carry out our handler function when all requests have completed?

Let's look at .when

https://api.jquery.com/jquery.when/

.when allows us to pass in one or more promise objects and execute the appropriate callback when all of them have been resolved. In other words when all server calls have completed successfully, the callback is executed.

var request;

request = apex.server.process(
    'My Process',
    {x01: myArgument},
    {type: 'POST'}
);

$.when(request).done(function(data) {
    console.log(data);
});

.when can take any number of promise arguments and it's even possible to pass in an array of promise objects using .apply. For example

var requests = [];

$('.rowData').each(function(i, e) {
    requests.push(
        apex.server.process(
            'My Process',
            {x01: $(e).val()},
            {type: 'POST'}
        )
    )   
});

$.when.apply(null, requests).done(function() {
    console.log('All requests have been processed');
});

By adding the promise object returned by each call to apex.server.process to an array and then passing this array to a .when, we can attach a .done handler that is only fired once all promises have been resolved.