Variable scoping continues to confound me (see my sample code below). I have three questions for my understanding, however, the bottom line is that I need metricsArray available in Position4 for further processing.
Q1: I have initialized the "metricsArray" array variable at the top of my function which I thought meant it had global scope in the entire function...is this correct? I have tried both let and var statements and neither change the results below.
Q2: If I try setting the return variables from myFunction (metricsArray_A and/or metricsArray_B) below to metricsArray, then I get a warning that the variable is already declared in the upper scope indicating that I am doing something incorrect. Regardless of the warning, Position1 is the only situation where the metricsArray contains data. Also, if I comment out the initialization line of code at the top of the function, then Position2, Position3 and Position4 all complain that metricsArray is not defined. Where should metricsArray be declared?
Q3: From the console.log, the only Position that contains data in the metricsArray variable is Position1. In other words, it appears to me that the global scope is not being held. What am I doing wrong?
Any advice would be most appreciated. I will buy a virtual doughnut and a cup of coffee for anyone that can help me out here!
Thanks,
Jay
-----------------------------------------
async function initalizeMetrics(secArr) { let metricsArray = []; //Main Loop secArr.forEach(async function (sec) { await getSection(sec).then((text) => { let newSection = sec.replace(/Upd/, "Orig") //////// Call myFunction and return metricsArray_A myFunction(sec, text).then((metricsArray_A) => { console.log("metricsArray_A = " + metricsArray_A) }) //////// Call myFunction and return metricsArray_B myFunction(newSection, text).then((metricsArray_B) => { console.log("metricsArray_B = " + metricsArray_B) metricsArray = metricsArray_B; console.log("Position1 - metricsArray = " + metricsArray) // <-Has data }) console.log("Position2 - metricsArray = " + metricsArray) // <-Empty }) console.log("Position3 - metricsArray = " + metricsArray) // <-Empty }); console.log("Position4 - metricsArray = " + metricsArray) // <-Empty }
OK...my apologies for the earlier large section of code...(and thank you abergquist, I knew about this feature in the code editor, but not here in the forum! I tried to manually make it more readable for the post...guess that was a fail...sorry about that.)
Anyway...
Here is it's simplest form I think.
I need metricsArray to have data in it.
Inside the forEach loop it is correct...outside it is blank (from it's initial declaration).
---------------------------------------------------------------------
async function initMetrics(secArr) { var metricsArray = {}; secArr.forEach(async function (sec) metricsArray = await myFunction(sec, "A"); console.log(metricsArray); }); console.log(metricsArray); }
Hi, Jay.
Also, to make your code more readable, you can edit your message, highlight all (and just) your code and click on the rightmost button on the resultant toolbar, the one that reads "Code Block". That will make your code nicely formatted rather than jammed and wrapping around.
Variable scoping in Javascript is a wondrous and mystical phenomenon. I believe that you will get what you want with var, which basically ignores block scoping. In the case of let, when you enter another block (e.g. function) within another block, then you've changed scope and the let won't be seen inside the inner block.
OK, so that wasn't so clear, but I agree that variable scoping in Javascript is vexing and confusing. At least to me.
As an aside, I'm not sure the best way to handle your case is to use a "global" variable. There's much to be said for passing information to a function, and then returning the result to be used by the call to the function. This helps partition your code and avoids confusing scenarios - not to to mention cryptic scoping situations that only a select few are able to decipher.