0

So I've just learned that Javascript is Single-threaded, and hence it causes problems running the same function multiple times at once. My scenario is as follows:

I render a User Profile through creating Div's by document.createElement("div") This User profile, displays a list of other profiles, also via document.createElement calls

The profiles are stored on Firebase, so obviously I first have to .get() these documents. Currently, my functions are structured like this:

function populateProfile (userId) {
  //
  var docRef = firestore.collection("profiles").doc(userId);

  docRef
    .withConverter(profileConverter)
    .get()
    .then((doc) =>  {

      var profile = doc.data();
      var name = profile.name
      var image = profile.image
      var about = profile.about
      var tagline = profile.tagline
      var industry = profile.industry

      /* Creating all kinds of elements here */

        docRef.collection("details").orderBy("order").get()
        .then((snapshots) => cleanData(snapshots))
        .then((items) => items.map((item) => createDetailsBlock(item)));

        /* more element stuff */


          })
    .catch((error) => {
      console.log("Error getting Document: "+error)
    })

}

function createDetailsBlock (item) {
  currentCount++

  var itemId = item.id;
  console.log("Fetching profile: "+itemId)

  var docRef = firestore.collection("profiles").doc(itemId);

  docRef.get()
        .then((snap) => {
          // get values
          var data = snap.data();

          var id = data.id;
          var type = data.type;
          var title = data.name;
          var image = data.image;
          var subtitle = data.industry;
          console.log("Rendering about item: "+id)

          /* Creating elements here */

        })

}

As you can see, I call the same function for each item in the array. That works actually absolutely fine for other parts of the website, but in this particular case, it created problems. The first item gets pulled from the database just fine, but any subsequent item gets "undefined" - given I now know JS is single-threaded, I assume it cause halfway through executing the first run, it starts the next and then variables get all jumbled up.

JM Gelilio
  • 3,482
  • 1
  • 11
  • 23
  • JS is in fact single-threaded. Each function call gets a copy of variables saved with it (see [scope](https://developer.mozilla.org/en-US/docs/Glossary/Scope)), so there should not be any issues. Could you clarify were you are getting `undefined`? – Vitalii Aug 03 '21 at 22:26
  • One more thing to note, `var` in JS is not [behaving intuitively](https://stackoverflow.com/a/11444416/14596856), so it's best to replace `var` with [`let`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let) – Vitalii Aug 03 '21 at 22:31
  • 1
    This is not a problem with threading so much as it's a problem that you're looping through promises and not waiting for them to resolve. – I'm Joe Too Aug 03 '21 at 23:20
  • Thanks Joe, got that after looking more into it, as well. I've managed to resolve the issue, not quite how its intended, but to prototype quality anyways... --> Waiting to resolve, would be with "await", but I can't use await,cause Gulp, Babel & Lint combo tell me I can only use it for async functions, and it's sorta ignoring that my call to Firebase functions IS async T-T – David Griffin Aug 05 '21 at 17:17

0 Answers0