SharePoint 2013: Implement Deferred And Promise Object In JavaScript Asynchronous Execute

Introduction

SharePoint 2013 Client Object Model is used to retrieve, update and manage the data in SharePoint 2013 library/List. SharePoint makes an Object model available in several forms but here, we are using Javascript Object Model.

  • JavaScript library(JSOM)
  • REST/OData endpoints

In this Javascript Object Model, we will use executeQueryAsync() but it will execute/ will not wait for success/ fail to complete. We need to make executeQueryAsync() behave synchronously.

It means the function will wait for async operations, which should be completed and should return some values.

We know that SharePoint JavaScript Client Object Model is asynchronous. However, sometimes we want to process the things in a synchronous way.

This can be done by using JavaScript callbacks and deferred/Promises. Let's first see an asynchronous example, which we will later convert to synchronous:

For this reason, JavaScript is having an option to use deferred/promise method do this operation.

Promise

The promises pattern significantly simplifies JavaScript code when you make an app, which must have multiple, nested asynchronous calls and it makes it very powerful.

Example

Your JavaScript code has to update multiple list items one by one to complete the basic operations and wait for the first one to execute.

However, Promise object also acts like a caching mechanism, where the success or failure function will be called immediately, if the Promise has already been fulfilled.

Promises object can make it easy to execute dependent asynchronous calls sequentially, which are based on the results.

Syntax

The deferred/ Promise object is very simple syntax and powerful method for sequentially updating in the list/ list items.

Initially, we need to declare the deferred object, as shown below.

  1. var deferred = $.Deferred();  

At the end of the function, we have to return Promise object.

  1. return deferred.promise();   

First, we will see about normal JavaScript execution. 

  1. <script type="text/javascript">  
  2.     var 0camlItems;  
  3.     $(document).ready(function () {  
  4.         //don't exectute any jsom until sp.js file has loaded.          
  5.         SP.SOD.executeFunc('sp.js''SP.ClientContext', getvalues);  
  6.     });  
  7.   
  8.     function getvalues() {  
  9.         retrivethelistitem('Tutorial list');  
  10.         console.log(“Execute  second after the retrieve list items ”);              
  11.     }  
  12.   
  13.     function retrivethelistitem(listTitle) {  
  14.         var clientContext = new SP.ClientContext.get_current();  
  15.         var olist = clientContext.get_web().get_lists().getByTitle(listTitle);  
  16.         var camlQuery = new SP.CamlQuery();  
  17.         ocamlItems = olist.getItems(camlQuery);  
  18.         clientContext.load(ocamlItems);  
  19.         clientContext.executeQueryAsync(  
  20.             Function.createDelegate(thisthis.success),  
  21.             Function.createDelegate(thisthis.failure)  
  22.         );  
  23.     };  
  24.   
  25.     function success(sender, args) {  
  26.         var listItemEnumerator = ocamlItems.getEnumerator();  
  27.         while (listItemEnumerator.moveNext()) {  
  28.             var olistItem = listItemEnumerator.get_current();  
  29. console.log(‘execute first ‘);  
  30.               
  31. console.log(olistItem.get_item('Title'));  
  32.         }  
  33.     }  
  34.   
  35.     function onQueryFailed(sender, args) {  
  36.         console.log('An error occured while retrieving list items:' + args.get_message());  
  37.     }  
  38. </script>   

Output

For the method given above, we will get the output given below.

Execute second after retrieving the list items.

execute first
NewListitem

Here, we are expecting success function, which should execute first. Unfortunately, the previous one executed. Sometimes it will cause a major issue when you are updating the list items.

Thus, we need to use Async operation to perform synchronously.

Let's see the deferred/ Promise function, as shown below. 

  1. <script type="text/javascript">  
  2.     var 0camlItems;  
  3.     $(document).ready(function () {  
  4.         //don't exectute any jsom until sp.js file has loaded.          
  5.         SP.SOD.executeFunc('sp.js''SP.ClientContext', getvalues);  
  6.     });  
  7.   
  8.     function getvalues() {  
  9.         retrivethelistitem('Tutorial list').done(function()  
  10. {  
  11.         console.log(“Execute  second after the retrieve list items ”);   
  12. }).fail(function()  
  13. {  
  14.  console.log(“Execute  second after the retrieve list items  failed”);   
  15. });             
  16.     }  
  17.   
  18.     function retrivethelistitem(listTitle) {  
  19. //Declare your deferred object here  
  20.       var deferred=$.Deferred();  
  21.         var clientContext = new SP.ClientContext.get_current();  
  22.         var olist = clientContext.get_web().get_lists().getByTitle(listTitle);  
  23.         var camlQuery = new SP.CamlQuery();  
  24.         ocamlItems = olist.getItems(camlQuery);  
  25.         clientContext.load(ocamlItems);  
  26.         clientContext.executeQueryAsync(  
  27.             Function.createDelegate(thisthis.success),  
  28.             Function.createDelegate(thisthis.failure)  
  29.         );  
  30. //Return your Promise Object  
  31. return deferred.promise();  
  32.     };  
  33.   
  34.     function success(sender, args) {  
  35.         var listItemEnumerator = ocamlItems.getEnumerator();  
  36.         while (listItemEnumerator.moveNext()) {  
  37.             var olistItem = listItemEnumerator.get_current();  
  38. console.log(‘execute first ‘);  
  39.               
  40. console.log(olistItem.get_item('Title'));  
  41. //Resolve your object here  
  42. deferred.resolve(olistItem );  
  43.         }  
  44.     }  
  45.   
  46.     function onQueryFailed(sender, args) {  
  47.         console.log('An error occured while retrieving list items:' + args.get_message());  
  48. //Reject your object here  
  49. deferred.reject(olistItem );  
  50.     }  
  51. </script>   

Output

For the code given above, we will get the output, as shown below.

execute first
NewListitem

Execute second after retrieving the list items.