Question: Making JS Functions Follow a STRICT Order (aka, I Still Don't Get Promises)
First, let me lay out what I want to do, in the simplest terms:
I have a series of functions that need to be called in a particular order; each function in that order has its own order it needs to follow.
My current code, simplified:
async function LastModuleFunction() { await FirstModuleFunction(); // Order:1 await SecondModuleFunction(); // Order: 2 // ...etc... await EighthModuleFunction(); // Order: 8 setTimeout(GoToNextPage(), 2000); // Order 9 } function GoToNextPage() { // some script irrelevant to this question... window.location.href = 'OtherPage.aspx'; // Order: LAST }
lastModule.js
async function FirstModuleFunction() { var obj = { item1: 0, item2: 0, item3: '' }; // you get the idea FirstModuleDataSaveProcess(); async function FirstModuleDataSaveProcess() { await FirstModuleDataFunction1(); // Order: 1A await FirstModuleDataFunction2(); // Order: 1B // I created a shared function for AJAX PostDataAjax('AutoSave_ModuleData.asmx/AutoSave_FirstModule', obj, true); // Order: 1C // The last parameter is just a boolean to tell the function if it should fire a "Saved!" // message (via Toast) upon success. } }
firstModule.js
$('#btnSaveAndFinish').on('click', async function() { $(this).prop('disabled', true); $(this).html(waitSpinner); // just a bootstrap "please wait" animation here LastModuleFunction(); });
moduleNavigation.js
The order MUST go in this pattern: 1A -> 1B -> 1C -> 2A -> 2B -> ... -> LAST
Each function in the sequence MUST wait for the previous to complete.
Boring backstory & context:
I have an aspx page with multiple UserControl modules (ascx). Which UC's, and how many, depend on the user and the time of day (it's a meeting recorder app that handles 4 different types of meetings each day).
Each time the user navigates to the next module (they come in on a bootstrap carousel), a series of functions prepares the data and sends it to a WebService class (asmx) via AJAX (see firstModule.js above). We tell the user this "auto-saves" the data as they go (which it does).
On the last module, the "next" button is replaced by a "save and finish" button. When clicked, this button goes through EACH of the previous modules again*, saves ALL form data to the database through each AJAX function, and THEN location.href
's to a different aspx page.
*The user is also able to skip ahead or back to a module, which doesn't trigger an "auto-save," so the app makes extra-sure all data is accounted for.
What's actually happening:
Most of the time, this works as intended. The functions fire in order, and the 2-second buffer I give LastModuleFunction()
is enough time to have the data saved and ready for the next page before it redirects.
...But sometimes, it doesn't/isn't.
There are two significant tells that indicate something's not right:
In
FirstModuleFunction()
, the WebService called in the AJAX updates a data row that holds the core information for that meeting; the "MeetingCompleted" column in that data row is changed from 'N' to 'Y'. The next page's code, atPage_Load
, checks if this value is indeed a 'Y'; if not, it redirects back to the original page with a specific query string that tells me that the check failed. So it looks like, in some cases,FirstModuleFunction()
doesn't complete before the redirect fires.When placing
console.log()
calls before each function inLastModuleFunction()
, they fire in the correct sequence on the console, each time I tested. However, when I place anotherconsole.log
insideFirstModuleFunction()
, for example, the console shows a different story:
1st module hit 2nd module hit 3rd module hit function inside 1st module hit <-- what the...? 4th module hit [etc.]
console
I'm now starting to think that simply using await
when calling async
functions isn't getting the job done. I can't remember where I read it would be this simple, but it appears I either misunderstood or was misinformed, hm? Apparently I need to use Promises...is that correct? Problem is, I could never wrap my head around how to make promises work with this exact sequence structure I need. Can someone help me understand what kind of structure I should be using?
Note: most of these functions do not return any value; they simply act as routines.