简体   繁体   中英

javascript: executing order of function - nested function return value before function finishes processing?

I'm just learning JavaScript, and it seems there is a lot of information for folks like me about the way it processes functions asynchronously.

While I am still trying to get my head around this, I find myself struggling with some sharepoint csom because of what I am trying to do. Perhaps I am just going about this completely wrong, but as I said, just learning.

Trying to use SP CSOM to get list data like this:

getGridData() {
    var gridURL = "https://mySite/ListData.svc/Projects";
    var request = new Sys.Net.WebRequest();
    request.set_httpVerb("GET");
    request.set_url(gridURL);
    request.get_headers()["Accept"] = "application/json";
    request.add_completed(onCompletedProjectCallback);
    request.invoke();
}

onCompletedProjectCallback(response, eventArgs) {
      var getProject = eval("(" + response.get_responseData() + ")");
      var buildMarkUp = '';
      for (var i = 0; i < getProject.d.results.length; i++)  {
         buildMarkUp += "<div>" + getProject.d.results[i].ProjectName + "</div>";
      }
}

This works great.

I do know about other methods such as spservices, but I like this as it seems to be faster for me and returns JSON which is preferable.

What happens when I want to use the ProjectID in the above to call another function and pass the id in order to get related values from a list.

However, I want to build the buildMarkUp string in order before it gets appended to the DOM(oh yeah jQuery btw). Something like this might be totally wrong, but it is what I was trying to do:

onCompletedProjectCallback(response, eventArgs) {
      var getProject = eval("(" + response.get_responseData() + ")");
      var buildMarkUp = '';
      for (var i = 0; i < getProject.d.results.length; i++)  {
         buildMarkUp += "<div>" + getProject.d.results[i].ProjectName + "</div>";

      //call nested function here so that I can go retrieve values for each ProjectID from another list
       var getOtherData = getRelatedData(getProject.d.results[i].ProjectID);
      }
}


getRelatedData(passedProjectID) {
     // have to use the same method as the original to get more sharepoint list data
      var relatedURL = "https://mySite/ListData.svc/Related$filter=ProjectID eq " + passedProjectID;
    var request = new Sys.Net.WebRequest();
    request.set_httpVerb("GET");
    request.set_url(relatedURL);
    request.get_headers()["Accept"] = "application/json";
    request.add_completed(onCompletedRelatedCallback);
    request.invoke();
}

This is where I am really struggling with this though.

A separate callback means it is not going back to the original function with data if I return right?
Does the original function keep processing and just fire the nested functions?
How can I control when/how/what values are returned to the original function then? Can I?

Basically what if I was trying to build a table, where each referenced project row contained data from other sharepoint lists, and I would need to control the order in which the string that I was going to append to the DOM got built?

A separate callback means it is not going back to the original function with data if I return right?

Yes. return returns from the function executing, but does not wait for the ajax load event and its handler to get the data.

Does the original function keep processing and just fire the nested functions?

Yes. It starts a bunch of ajax requests, and gets back undefined for each of them.

How can I control when/how/what values are returned to the original function then? Can I?

You will need to use callbacks, you never will " return " the values.

You are correct that a function that executes a web request continues immediately and cannot return the data from that call. You need to code the callbacks to add the data they collected to a public data structure -- perhaps create an object that accumulates the data as new attributes. When you have collected all of the data, the last callback can build the HTML elements. If you are doing multiple simultaneous AJAX requests, then each callback can call a common function to see if all requests have finished. For example:

function checkLoadingComplete() {
    if (loadedData.project && loadedData.relatedData && loadedData.summaryData) {
         //now build the HTML elements
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM