1

Defined variable in global:

var domArray = [] //will have multiple string
var onQueueDom = [] //will have 1 string only
var onQueueDomStatus = ["N"] //will one of the status: "N", "P","D"
var processedNum = 0

I create a function which will return True or False, it will wait 3 seconds only run the if else:

function checkIfPending(){

    console.log('checkIfPending being executed ')

    setTimeout(function(){
        if(onQueueDomStatus[0] == "D"){



        console.log("Process Done, returning True")

        return true

        console.log("True has been returned, you shouldn't seeing this")


        }
        else if(onQueueDomStatus[0] !== "D" || onQueueDomStatus[0] !== "N" && onQueueDom !== ""){
            console.log("Still Processing, will re-check in 3 second")

            return false
        }
        else {
            console.log("No domain on Queue but status not clear")
            console.log("Clearing status...")

            onQueueDomStatus[0] = "D"

            console.log('setting onQueueDomStatus to ' + onQueueDomStatus[0])

            console.log("Status changed to D & returning True")

            return true

        }
    }, 3000);

}

i want to use the above function as the condition of while loop, but it will not process the code in the While loop even the onQueueDomStatus[0] == "D":

while(checkIfPending() == true){

                console.log('while loop is running')

                onQueueDomStatus[0] = "N"
                console.log('setting onQueueDomStatus to ' + onQueueDomStatus[0])

                movetoQueue()
                console.log('Executing movetoQueue')
            }

Assuming the onQueueDomStatus[0] is always "D", but it still not working.

Side question: is the while loop will wait 3 seconds to execute everytime?

Jerry
  • 1,455
  • 1
  • 18
  • 39
  • @Shubham: No, that won't help. – T.J. Crowder Dec 18 '17 at 06:56
  • `while` is synchronous and `checkIfPending` is asynchronous because `setTimeout` is async. You need to use constructs for handling async code like callbacks or promises. – nem035 Dec 18 '17 at 06:57
  • its a setTimeout in your function.so your function willl return undefined every time you call it. – zabusa Dec 18 '17 at 06:58
  • @nem035 any way to achieve the 3 sec delay if i remove it from my `checkIfPending` function? – Jerry Dec 18 '17 at 07:01
  • @Jerry, can we have a chat, I can help you with concept and implementation (using await and promise), just need to clarify the requirement – Akshay Vijay Jain Dec 18 '17 at 08:46

3 Answers3

2

checkIfPending has no return value, so calling it results in the value undefined. The callback you're passing setTimeout has a return value (though setTimeout ignores it), but checkIfPending does not. checkIfPending cannot return any value it derives from an asynchronous operation (more here).

while is a synchronous control-flow structure.* You can't use the result of an asynchronous function as the condition in a while.

Edit: gurvinder372 has done a good job of showing you how to restructure things to handle the asynchronicity.


* The semantics of while can be made asynchronous inside an ES2017+ async function if you use await, but under the covers, what really happens is that the function is rewritten not to use while.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • i want to use synchronous method to achieve my objective, anyway to achieve the 3 sec delay if i remove it from my `checkIfPending` function? – Jerry Dec 18 '17 at 07:03
  • @Jerry: No *reasonable* way, no. The unreasonable way is to completely lock up the UI of the page: `var stop = Date.now() + 3000; while (Date.now() < stop) {}`. I strongly urge you not to do that. :-) – T.J. Crowder Dec 18 '17 at 07:04
  • @Jerry: ...and looking at what you're checking (`onDomQueueStatus[0]`), a busy-wait wouldn't work anyway, because while you're busy-waiting, nothing else can update `onDomQueueStatus[0]`. – T.J. Crowder Dec 18 '17 at 07:09
1

You need to invoke callback instead of returning true or false

function checkIfPending( exitCallback, trueCallback ){
    console.log('checkIfPending being executed ')
    setTimeout(function(){
        if(onQueueDomStatus[0] == "D"){
           trueCallback (); //invoke callback which signals that checkPending should continue
           checkIfPending( exitCallback, trueCallback );
        }
        else if(onQueueDomStatus[0] !== "D" || onQueueDomStatus[0] !== "N" && onQueueDom !== ""){
            exitCallback(); 
        }
        else 
        {
            onQueueDomStatus[0] = "D";
           trueCallback (); //invoke callback which signals that checkPending should continue
           checkIfPending( exitCallback, trueCallback );
        }
    }, 3000);
}

And use this as

checkIfPending( function(){
    //console.log( "while loop ended" );
}, function(){
    onQueueDomStatus[0] = "N";
    movetoQueue();
})
gurvinder372
  • 66,980
  • 10
  • 72
  • 94
  • 1
    @T.J.Crowder I have created two events, one for exit condition and one to signify that this pseudo-while loop must continue. – gurvinder372 Dec 18 '17 at 07:09
1

This code will help you

function getPromise(){
 return new Promise((resolve,reject)=>{
 setTimeout(function(){
        if(onQueueDomStatus[0] == "D"){
        console.log("Process Done, returning True")
        resolve(true)
        }
        else if(onQueueDomStatus[0] !== "D" || onQueueDomStatus[0] !== "N" && onQueueDom !== ""){
            console.log("Still Processing, will re-check in 3 second")
            resolve(false)
        }
        else {
            console.log("No domain on Queue but status not clear")
            console.log("Clearing status...")
            onQueueDomStatus[0] = "D"
            console.log('setting onQueueDomStatus to ' + onQueueDomStatus[0])
            console.log("Status changed to D & returning True")
            resolve(true)
        }
    }, 3000);
})
}
async function final(){
 var d = await getPromise(); // d will contain boolean after specified delay
 while(d == true){
  onQueueDomStatus[0] = "N"
  movetoQueue();
  d = await getPromise(); 
 }
}
Akshay Vijay Jain
  • 13,461
  • 8
  • 60
  • 73