2

Problem:

  1. User makes some selection on the UI
  2. Spinner is displayed to the user
  3. Two server-side actions are invoked. First Action1 and thenAction2.

When should I hide the spinner? in Action1 callback or Action2 callback?

I created a simple example in lightning to check if Action2 callback is invoked before Action1 callback if Action1 execution takes longer time but still Action2 callback is invoked after Action1 callback.

So can I safely assume that Action2 callback always executes after Action1 callback and hide the spinner in Action2 callback?

Experts please advise.

Here is a simple reproducible example:

HelloWorldApp.app:

<aura:application extends="force:slds" controller="HelloWorldApexController">
    <aura:attribute name="foo" type="String"></aura:attribute>
    <aura:attribute name="bar" type="String"></aura:attribute>
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>

    <aura:text value="{!v.foo}"></aura:text>
    <br/>
    <aura:text value="{!v.bar}"></aura:text>

</aura:application>

HelloWorldAppController.js:

({
    doInit: function(component,event,helper){
        helper.loadData(component);
    }   
})

HelloWorldAppHelper.js:

({
    loadData : function(component){
        var action1 = component.get("c.getFooValue");

        action1.setCallback(this, function(a) {
            component.set("v.foo", a.getReturnValue());
            console.log('getFooValue execution finished: ' + Date.now());
        });
        $A.enqueueAction(action1);

        var action2 = component.get("c.getBarValue");

        action2.setCallback(this, function(a) {
            component.set("v.bar", a.getReturnValue());
            console.log('getBarValue execution finished: ' + Date.now());
        });
        $A.enqueueAction(action2);        
    }
})

HelloWorldApexController.cls:

public class HelloWorldApexController {

    @AuraEnabled
    public static String getFooValue() {
        //Code to make the execution of getFooValue method to execute longer
        //hoping getBarValue method execution finishes before getFooValue. 
        Long startingTime = System.now().getTime();
        Integer delayInMilliseconds = 4000; 
        while (System.now().getTime() - startingTime < delayInMilliseconds)  {
        }
        return 'Boston';
    }

    @AuraEnabled
    public static String getBarValue() {
        return 'New York';
    }
}

Ran multiple times and it always shows that getBarValue callback is executed after getFooValue callback even though getFooValue execution on the server takes more time than getBarValue method.

console output:

Even the debug log shows that getBarValue method is invoked after getFooValue method finished executing but I somehow believe it may not be true in all conditions and can someone please confirm if this is always the case?

Output from Debug log: (Removed other irrelevant parts from the debug log)

11:46:56.0 (689064)|CODE_UNIT_STARTED|[EXTERNAL]|01p37000003HbN0|HelloWorldApexController.getFooValue 11:46:56.0 (72051839)|CODE_UNIT_FINISHED|HelloWorldApexController.getFooValue 11:46:56.84 (84033626)|CODE_UNIT_STARTED|[EXTERNAL]|01p37000003HbN0|HelloWorldApexController.getBarValue 11:46:56.84 (84236962)|CODE_UNIT_FINISHED|HelloWorldApexController.getBarValue

2 Answers 2

4

Lightning creates an action queue, which buffers up requests and sends them periodically to the server. Like Visualforce RemoteAction methods, requests are processed serially (as opposed to parallel), in order, in batches of a few milliseconds. The platform has no way of knowing if one method will take longer than the other, and there's no benefit to reordering, because all of the responses will arrive in a single package anyways. I don't know if it's guaranteed by the documentation, but it's probably safe to assume that any request enqueued before another will be processed first, regardless of the processing time required.

Further Reading:

2
  • Thanks for those links! Learning some pretty cool stuff from it.
    – javanoob
    Feb 22, 2017 at 19:02
  • @javanoob You're welcome! Glad I could help.
    – sfdcfox
    Feb 22, 2017 at 19:16
3

Order of action execution is not guaranteed on the server. Today actions execute serially in a specific order but that may change.

For your specific scenario, a basic gating mechanism is required to know when to hide the spinner. E.g. Increment a counter on enqueue, decrement on callback and if it's 0 hide the spinner.

1
  • I like the approach of using a counter to check all callbacks finished and then hide the spinner. Thanks for the answer.
    – javanoob
    Feb 24, 2017 at 15:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .