TransWikia.com

running multiple ajax calls synchrnously in SharePoint rest api

SharePoint Asked by Adarsh Awasthi on October 25, 2021

I have written javascript REST API code with two AJAX Calls. Code is like below:

$.ajax({

onSuccess(function(){

for(let i=0;i<=data.d.results.length;i++)
{
   GetEmployeeDetailsFromOtherList(data.d.results[i].EmployeeID);
}
});
});


function GetEmployeeDetailsFromOtherList(EmpID)
{
 $.ajax({

onSuccess(function(){

for(let i=0;i<=data.d.results.length;i++)
{
   //Show Employee name and all other details in HTML table.
}
});
});
}

So in this code, 2nd ajax call is fetching details of emaployee from another list and there can be 3rd nested call as well by passing arguments from 2nd call.

As i am new to javascript, how i can achieve this nested dependent ajax call funtionality without using async:false as without using that, data is not getting fetched and completion of all these requests taking too much time.

Please assist with the suitable approach i need to follow in these scenarios where i have to pass data from one ajax call to another.

2 Answers

Since you are using jQuery, you can use the jQuery Deferred object, which is similar to a regular javascript Promise, in order to control the execution flow of your multiple requests. What you need to do is return a deferred.promise() from the functions where you make the ajax calls, and only resolve() the promise when you are satisfied that the next call has completed successfully, or that there doesn't need to be another ajax call. So you would set up your functions something like this (I have included numbered comments to illustrate the execution order of the code within each function, but be aware that everything inside the second request function happens between steps 3 and 4 of the initial request function):

function makeInitialRequest() {
    var initialDeferred = $.Deferred();
    // 1. make the initial request
    $.ajax({

    }).done(function(data) {

        // 3. request succeeded

        // map through the results to make your second requests,
        // but _store_ the returned promises so you know when 
        // the second requests have all resolved
        var secondRequests = data.d.results.map(function(resultItem) {
            // the map function here is returning the promisse
            // that is returned from the makeSecondRequest function
            return makeSecondRequest(resultItem.EmployeeID);
        });

        // wait until all second requests have finished before
        // resolving the initial promise
        $.when.apply($, secondRequests).done(function() {
            
            // 4. all second requests completed
            //    so we can tell the calling function
            //    that everything is complete and it's ok to proceed
            initialDeferred.resolve();

        }).fail(function() {
            // 4. deal with the error
            initialDeferred.reject();
        });

    }).fail(function(xqXhr, code, error) {

        // 3. deal with the error
        initialDeferred.reject();
    });
    // 2. return an unresolved promise
    return initialDeferred.promise();
}

function makeSecondRequest(userID) {
    var secondDeferred = $.Deferred();
    
    // 1. make request
    $.ajax({

    }).done(function(data) {

        // 3. request succeeded
        if (data.d.SomeValue) {
            // if you need to make another call, go ahead,
            // and wait for that to be finished before resolving the promise
            makeThirdRequest(data.d.SomeOtherValue).done(function() {
                // 4. the third request succeeded
                //    so we can tell the makeIntitialRequest function
                //    that everything is complete and it is ok to proceed
                secondDeferred.resolve()
            }).fail(function() {
                // 4.
            });
        } else {
            // no need to wait for another call,
            // so just tell the makeIntialRequest function
            // it is ok to proceeed
            secondDeferred.resolve();
        }
    }).fail(function(jqXhr, code, error) {
        // 3.
    })
    // 2. return the promise
    return secondDeferred.promise();
}

So you can keep nesting other calls, as long as you make them return deferred.promise()s that you then resolve() when it's ok for the previous function to continue.

(It can also get more complex by calling resolve(someData) with some data, which will actually return that data out to the calling function, but I'm not going to get into that here.)

Then, in your main code, you just do:

// some code
// some code
makeInitialRequest().done(function() {
    // continue with your code
    // knowing that all nested ajax calls are complete
}).fail(function() {
    // deal with failure
});

Oh, also, keep in mind I have rejected the promises on errors, but be aware that that will pass the error state up to the calling function, meaning, in this "main code" example just above, if the makeInitialRequest function calls reject() on the initialDeferred, you will never get to the done function where it says "continue with your code knowing all nested ajax calls are complete". Instead, it will go to the fail function. This is important because sometimes certain errors mean that it's impossible to continue, so you do want to reject those up to prevent further code execution, but sometimes the errors may not mean that it's impossible to continue, so you just may want to try to deal with those locally within the functions where they occur, but still resolve the promise so that the calling function can proceed anyway.

Answered by Dylan Cristy on October 25, 2021

Answered by João Silva on October 25, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP