Inside of this for-loop, I hope to force it to run the AJAX code block first. With the result (i.e. data.LocationId), I want to save that on the server, and then run the loop with i decreasing.
If you see my console.log, I hope it could be:
asyncProcess
data.LocationId 7615
asyncProcess
data.LocationId 7614
asyncProcess
data.LocationId 7613
But actually it is:
asyncProcess
asyncProcess
asyncProcess
data.LocationId 7615
data.LocationId 7614
data.LocationId 7613
How can this be achieved?
This is my code:
for (i = projectAreaSet.length-1; i >= 0; i--)
{
function asyncProcess(geometry)
{
console.log("asyncProcess");
var deferred = new Deferred(); //Dojo, not jQuery
var locationProfile = { ProjectId: projectId }
$.ajax({
type: "POST",
data: JSON.stringify(locationProfile),
url: "api/LocationProfile/Create",
contentType: "application/json",
})
.success(function (data)
{
LocationIdSet.push(data.LocationId);
console.log("data.LocationId ", data.LocationId);
var currentProjectGraphic = new esri.Graphic(geometry, newSymbol, attributes =
{ "ID": data.LocationId, "Type": 1}, null);
var currentLayer = that.map.getLayer("Project");
currentLayer.applyEdits([currentProjectGraphic], null, null);
deferred.resolve();
});
return deferred.promise;
}
var saveProject = asyncProcess(projectAreaSet[i]);
}
Since it appears that your ajax calls are all independent of one another (one doesn't depend on the other), you can run them all in parallel and use promises to keep the result in order so you can then process the result in order. This will generally be a faster end-to-end execution time, but will still let you process the results in order. You can do that using jQuery promises like this:
While I support jfriend00's suggestion of running the requests in parallel, you specifically asked:
If you really want them run serially/sequentially, one technique would be to run the next iteration from the success() callback.
In the code below, the for statement has been removed, and i has been made a parameter of the function asyncProcess(). Then in the success callback, if the value of i is greater than 0, it calls the function again after subtracting one value from i (just like the for loop did).
See this demonstrated in this plunker.
Update:
After reading the discusssion of the answer, it appears you will aim for a parallel approach. For that, since jQuery is being utilized, look at using the .when() function- passing an array of promises (e.g. Returned by $.ajax()).
Take a look at this updated plunker. You will notice that the function asyncProcess has been updated to return the call to
$.ajax()
, which is a jqXHR object, which "implements the Promise interface"1.Using that change, the promises can be added to an array. Then use the spread operator (i.e.
...
) to pass the promises to $.when.The spread operator is added in ES-6 so older browser like IE won't support it. If support is needed for such browsers, apply can be used to call $.when with those promises.
In the .done() callback of the call to
$.when()
, each argument is an array, where the first element is the data. Putting it all together, we have code like below:†Well, actually you asked "How to make this happen" in the original post but somebody edited your post... 1https://api.jquery.com/jquery.post/#jqxhr-object