Hi friends, In this post, I will illustrate promises with code example. With the help of this post you can easily used promises in your lightning component. So without wasting time let's get started.

Promises in lightning component 

In lightning component promises used to call apex function asynchronously. It can simplify code that handles the success or failure of asynchronous calls. Lighting components had improved its performance by asynchronous call of apex function but promises are one of the easiest way to deal with asynchronous call without using callbacks. When you chaining multiple calls in lightning component its made execution little bit slow but in promises chaining javascript call doesn't impact on execution speed. Code written using promises is easy to manage because of it's structure.

Let's see a code example that helps a lot to understand promises.

In my example, I have performed same action twice with minor difference,

1. Without $A.getCallback()

2. With $A.getCallback()

I will let you know the reason with following example.

PromisesHandler.apxc

 public class PromisesHandler {
@AuraEnabled public static Object serverSideAction1(String input) {
return input+'-Apex1';
}

@AuraEnabled public static Object serverSideAction2(String input) {
return input+'-Apex2';
}

@AuraEnabled public static Object serverSideAction3(String input) {
return input+'-Apex3';
}
}
PromisesComponent.cmp
 <aura:component controller="PromisesHandler" implements="flexipage:availableForAllPageTypes" access="global" >
<button onclick="{!c.onclick}">Method 1</button><br/><br/>
<button onclick="{!c.onclick2}">Method 2</button>
</aura:component>
PromisesController.js
 ({
onclick : function(component, event, helper) {
helper.apex(component,'serverSideAction1',{ input : "Param"})
.then(function(result){
console.log('Call 1 : ' , result );
return helper.apex(component,'serverSideAction2',{ input : result });
})
.then(function(result){
console.log('Call 2 : ' , result );
return helper.apex(component,'serverSideAction3',{ input : result });
})
.then(function(result){
console.log('Call 3 : ', result);
})
.catch(function(error) {
console.log(error[0].message);
});
},

onclick2 : function(component, event, helper) {
helper.apex(component,'serverSideAction1',{ input : "Param"})
.then(
$A.getCallback(function(result){
console.log('Callback 1 : ' , result );
return helper.apex(component,'serverSideAction2',{ input : result });
}),
$A.getCallback(function(error){
console.log(error[0].message);
})
)
.then(
$A.getCallback(function(result){
console.log('Callback 2 : ' , result );
return helper.apex(component,'serverSideAction3',{ input : result });
}),
$A.getCallback(function(error){
console.log(error[0].message);
})
)
.then(
$A.getCallback(function(result){
console.log('Callback 3 : ' , result );
}),
$A.getCallback(function(error){
console.log(error[0].message);
})
)
},
})
PromisesHelper.js
 ({
apex : function(component, apexAction, params ) {
return new Promise( $A.getCallback( function( resolve , reject ) {
var action= component.get("c."+apexAction+"");
action.setParams( params );
action.setCallback( this , function(callbackResult) {
if(callbackResult.getState()=='SUCCESS') {
resolve(callbackResult.getReturnValue());
}
if(callbackResult.getState()=='ERROR') {
console.log('ERROR', callbackResult.getError() );
reject(callbackResult.getError());
}
});
$A.enqueueAction(action);
}));
},
})

Output: Output will be same on click of both button.

I have made some changes(pass object rather than string to generate exception) in component controller.js file to understand the difference between both methods

PromisesController.js

 ({
onclick : function(component, event, helper) {
helper.apex(component,'serverSideAction1',{ input : "Param"})
.then(function(result){
console.log('Method 1 : ' , result );
return helper.apex(component,'serverSideAction2',{ input : {param:"1"} });
})
.then(function(result){
console.log('Method 1 : ' , result );
return helper.apex(component,'serverSideAction3',{ input : result });
})
.then(function(result){
console.log('Method 1 : ', result);
})
.catch(function(error) {
console.log(error[0].message);
});
},

onclick2 : function(component, event, helper) {
helper.apex(component,'serverSideAction1',{ input : "Param"})
.then(
$A.getCallback(function(result){
console.log('Method 2 : ' , result );
return helper.apex(component,'serverSideAction2',{ input : {param:"1"}});
}),
$A.getCallback(function(error){
console.log(error[0].message);
})
)
.then(
$A.getCallback(function(result){
console.log('Method 2 : ' , result );
return helper.apex(component,'serverSideAction3',{ input : result });
}),
$A.getCallback(function(error){
console.log(error[0].message);
})
)
.then(
$A.getCallback(function(result){
console.log('Method 2 : ' , result );
}),
$A.getCallback(function(error){
console.log(error[0].message);
})
)
},
})

Output: 

Differences: When both button clicked following points are came out.

1. Without $A.getCallback() - When error happen code will stop executing immediately and error message logged

2. With $A.getCallback() - When error happen error message logged and  code move to next execution point .

Hope you like this post, for any feedback or suggestions please feel free to comment. I would appreciate your feedback and suggestions.
Thank you.