1

Is there any best practice how to execute an asynchronous function multiple times (JavaScript, SharePoint, JSOM)? Think of this scenario:

// simplified
function MultipleExec() 
{
   var a = GetListData('ListA');
   var b = GetListData('ListB');
   var c = GetListData('ListC');
}

function GetListData(listName) 
{
   var context = new SP.ClientContext.get_current();
   var spList = context.get_web().get_lists().getByTitle(listName);
   [..]
   context.load(listItems);

   context.executeQueryAsync(function(sender, args) 
   {
      var listItemsEnumerator = listItems.getEnumerator();
      var data = '';

      while (listItemsEnumerator.moveNext()) 
      {
         var listItem = listItemsEnumerator.get_current();
         data += listItem.get_item('Title') + '\n'
      }

      return data;    
   }
}

Promises? How should promises be implemented? And what if I dont want my code do act synchronously? Is it even good practice to reuse code like this or should I think completely different?

  • Do you have jQuery available? – Rothrock Nov 2 '17 at 15:48
0

Sync calls are not good pratices and are not allowed by modern browsers anyway.

Here you have two options:

  1. Parallel calls (so all the requests will be done at the same time)
  2. Or one by one call

In both cases I recommend using Promise (with polyfill).

For the first case, the parallel calls:

function MultipleExec() 
{
  Promise.all([
    GetListData('ListA'),
    GetListData('ListB'),
    GetListData('ListC')
  ]).then(function(results) {
    console.log(results[0]) // data from ListA
    console.log(results[1]) // data from ListB
    console.log(results[2]) // data from ListC
  })
}

In the second case (one call after the other one):

function MultipleExec() 
{
  var dfd = Promise.resolve();
  var res = ["ListA", "ListB", "ListC"].map(function(list) {
    dfd = dfd.then(function() {
      return GetListData(list);
    });
    return dfd
  });
  Promise.all(res).then(function(results) {
    console.log(results[0]) // data from ListA
    console.log(results[1]) // data from ListB
    console.log(results[2]) // data from ListC
  })
}

And for both of them the GetListData will look like that:

function GetListData(listName)
{
  return new Promise(function(prom_res, prom_rej) {
    var context = new SP.ClientContext.get_current();
    var spList = context.get_web().get_lists().getByTitle(listName);
    [..]
    context.load(listItems);

    context.executeQueryAsync(function(sender, args)
    {
       var listItemsEnumerator = listItems.getEnumerator();
       var data = '';

       while (listItemsEnumerator.moveNext())
       {
          var listItem = listItemsEnumerator.get_current();
          data += listItem.get_item('Title') + '\n'
       }

       prom_res(data);
    }
  })
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.