-1

I have the following node js script:

const rp = require('request-promise')
let result = ''
let asyncdone = false
async function m() {
    return await rp.get('http://google.com')
}

m().then((html) => {
    result = html
    asyncdone = true
}).catch((e) => console.log(e))

while (!(asyncdone)) {
    console.log('processing...')
}
console.log(result)

When ran, the loop is infinite.
'processing...' keeps printing even though the async function should have set the asyncdone boolean as true, and thus break the loop, then log the result.

What am I not understanding?

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
nas96
  • 1
  • 2
  • Why are you using a while loop when you already an use promises? That's the whole point of async/await, that you can wait for an async task to finish, and not have to wait like this... – Andrew Li Dec 16 '17 at 17:20
  • OMG! This is the worst idea ever! The `while` loop is totally *blocking*. It will loop infintely, never giving control back to the event loop to run your asynchronous code. ‍♂️ – skylize Feb 01 '18 at 01:41

2 Answers2

0

I'll change the code to the following one if you only want to log processing... once.

var statuslogged = false;
while (true) {
  if (!statuslogged) {
    console.log('processing...');
    statuslogged = true;
  }
  if (asyncdone) {
    console.log(result)
  }
}
Andrew.Wolphoe
  • 420
  • 5
  • 18
  • it does not break out of the _while (!(asyncdone)) {.......}_ loop. the result does not get logged. the aim is for _processing..._ to be repeatedly printed until the result is available. – nas96 Dec 16 '17 at 17:08
  • @nas96 my fault sir, I misunderstood your question I updated the code in my answer – Andrew.Wolphoe Dec 16 '17 at 17:15
0

while is actually doing the right thing.

Since it's checking the condition continuously without any delay and getting true everytime, it's printing the info on console, if it does Million checks in a second and the conditions are met, the console will print the string.

So, we need to add a timeout/interval (called pollInterval) so that it checks only after desired time.

I have a different solution for your problem. You want to show progress/a filler text while the promise is going on.

const rp = require('request-promise')

// The base wrapper to stop polluting the environment
async function getHTML(url) {

    // A sample filler function
    function doSomethingElse() {
        console.log(`Processing`);
    }

    // a filler function to use it later inside
    function ensureData({
        fillerFn,
        pollInterval = 500
    }) {
        let result;

        // grab the data and set it to result async
        rp.get(url)
            .then((html) => {
                result = html
            })
            .catch((e) => console.log(e))

        return new Promise(function(resolve, reject) {
            // a self-executing function
            (function waitForFoo() {
                // if there is result, resolve it and break free
                if (result) return resolve(result);

                // otherwise run the filler function
                fillerFn()

                // execute itself again after the provided time
                setTimeout(waitForFoo, pollInterval);
            })();
        });
    }

    // return or run it
    ensureData({
            fillerFn: doSomethingElse,
            pollInterval: 500
        })
        .then((result) => {
            console.log(result)
        })
}

getHTML('http://httpbin.org/ip');
Md. Abu Taher
  • 17,395
  • 5
  • 49
  • 73