0

The basic premise of this is that I am trying to have a function within the class Manager wait for a value to be present before it begins. I've tried every variation of the code below and cannot seem to make it work. It does log "Special value found" so I know that it's returning the value. Why does this not work? I clearly don't understand async well.

async function getValue (file)  {
    let specialI = false;
    fs.readFile(file, 'utf8', (err, fileContents) => {
        for (let i in data) {
            if (data[i] === GOOD) {
                specialI = true;
            }
        }

        if (specialI) {
            console.log("Special value found!");
            return data[specialI];
        } else {
            return false;
        }
    } 
}

class manager() {
    async waitForSpecial() {
       let value;
       value = await getValue("file.json");
       if (value) {
           console.log("Wow it worked!");
       } else {
           console.log("Still no value...");
           await sleep(500);
           this.waitForSpecial();
       }
    }
}
dir
  • 661
  • 3
  • 13

2 Answers2

1

You're not returning anything from "getValue" so its immediately resolving nothing when you await it with await getValue("file.json")

Then it probably prints Special value found! just after it prints Still no value

You need to await the fs.readFile result as well by encapsulating the readFile invocation in a Promise like so:

async function getValue(file) {
    let specialI = false;
    return await new Promise((resolve, reject) => {
        fs.readFile(file, 'utf8', (err, fileContents) => {
            for (let i in data) {
                if (data[i] === GOOD) {
                    specialI = true;
                }
            }

            if (specialI) {
                console.log("Special value found!");
                resolve(data[specialI]);
            } else {
                resolve(false);
            }
        })
    });
}

class manager {
    async waitForSpecial() {
        let value;
        value = await getValue("file.json");
        if (value) {
            console.log("Wow it worked!");
        } else {
            console.log("Still no value...");
            await sleep(500);
            this.waitForSpecial();
        }
    }
}
gabriel.hayes
  • 2,267
  • 12
  • 15
  • This solution still yields the exact same output, and I have no idea as to why. I tried this earlier as well. – dir Oct 21 '19 at 20:21
  • What's the output you're getting? Is it "Still no value..." then "Special value found!"? – gabriel.hayes Oct 21 '19 at 20:22
  • Yes, I'm getting that output. – dir Oct 21 '19 at 20:23
  • @R8T3D Hm... I'm running a minimal version of the snippet I've posted (commented out the for statement; resolved a simple 'voila' if the fileContents contained the text 'test') and it works fine. The output I'm getting is "Special value found!" and "Wow it worked!" (in that order) – gabriel.hayes Oct 21 '19 at 20:27
  • `for (let i in data) {` what is `data`? – Bravo Oct 21 '19 at 20:29
  • `data[specialI]` ... what is `data[true]` since `specialI` is `true` – Bravo Oct 21 '19 at 20:30
  • @Bravo it appears to be code that falls -mostly- outside of the scope of these two functions; for my minimally reproduced version I refactored to remove `data`, `GOOD`, and `specialI` references. – gabriel.hayes Oct 21 '19 at 20:33
  • 1
    I got it, your solution works swimmingly. Cheers. – dir Oct 21 '19 at 20:36
-1

Since it's async, it will never wait for a value to proceed. It's always better to write all the async stuff together...

If you must do it that way so I suggest you try to use a flag in a while block, although it kills the concept of async, or try to use a more accessible variable testing while it's null.

Thiago E S
  • 75
  • 3