Handling Multiple (REST) Server Requests One At A Time

I am working with the SharePoint REST API, but this issue is not specific for SharePoint or even a REST API. An issue with the SharePoint server is that if you have multiple HTTP (REST) requests, particularly to modify SharePoint “databases” (apps/lists/libraries) with POST requests, it is better to queue them up and wait for the HTTP response of one before sending the next one, rather than just firing off the requests one by one to the server and waiting for the responses to come one by one.

I use the JQuery AJAX [ $.ajax() ] to form the actual HTTP request within my own library for the API. Where I need things to be asynchronous, I use Promises.

The simple task is to take a queue of the information I need to make the POST request. That’s basically a JavaScript array of objects whose properties might be the url (or part of url) and the POST body/data. A library of methods for the REST API then take each array element and sends the request, and then waits for the success or error callback to be called to trigger then next request. Should be simple enough.

In the code block below is a pattern (?) function that is supposed to manage this one-at-a-time or queueing or serial processing.

It requires two parameters: ‘opFunction’ is the method to be called that would handle a single REST request (not multiple), and ‘itemset’ is the array of objects whose properties will be read by ‘opFunction’ to set up the single REST request for each array element. The ‘responses’ variable inside the function is an array to keep track of all responses. The function encloses a function ‘iterate’ which is to be called (recursively?)

To initialize this, the processing ‘serialSPProcessing’ function returns a promise to the caller and then calls ‘iterate’ starting with the first element. Within ‘iterate’, which has access/scope to the containing function’s variables, it calls opFunction (which also returns a promise) and waits for success/failure report (.then/.catch blocks) and then stores the result, before calling the next element for the data for the next request. If there is no more processing to be done in ‘iterate’, execution returns to the outer function where resolve() is called to return the results.

The problem I am having is that there is some HTTP response coming back considered an error (for instance, a 404 Not Found) that totally unwinds the entire call stack, bypasses that function and returns to the first scope/level of execution without the information I need. Note that I will purposely make requests, for instance, to look for things I don’t expect to find–that is, 404 requests–and that too is information to ensure something is not already existing.

I thought I had this working before, but I refactored the script and am seeing this crash out/unwinding of the call stack. I think it might have to do with the Promise that has only the resolve() method called, and that the Promise should also have a reject() method or it unwinds the call stack like that. I am not quite sure how to experiment with that. Suggestions?

function serialSPProcessing(opFunction, itemset) {
	let responses = [ ];
	return new Promise((resolve) => {
		iterate(0);
		resolve(responses);
	});
	function iterate(index) {
		let datum;

		if ((datum = itemset[index]) != null)
			opFunction(datum).then((response) => {
				responses.push(response);
				iterate(index + 1);
			}).catch((response) => {
				responses.push(response);
				iterate(index + 1);
			});
		return;
	}
}

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.