1

I have a simple if statement, which I don't understand !

var  internetConnection ="0"
// Checking the internet connection at the start 
  require('dns').resolve('www.google.com', function(err) {
    if (err) {
        internetConnection="1"
         console.log("Internet connection  NO",internetConnection)
    } else {
        internetConnection="0"
        console.log("Internet connection  yes ",internetConnection)
  } 
  });
  console.log("Internet connection  test",internetConnection)

here is the output:

Internet connection  test 0
Internet connection  NO 1

does anybody understand why the correct value isn't been set? I've expected :

Internet connection  test 1

thanks in advance for any hint!

Engine
  • 5,360
  • 18
  • 84
  • 162
  • The dns promise api is async. Your test log runs and outputs a 0 before the other code can reassign the variable to 1 https://nodejs.org/api/dns.html#dns_dns_promises_api – Nick Mar 11 '20 at 06:48
  • @Nick thanks for your reply, is there a word around for this ? – Engine Mar 11 '20 at 06:49

4 Answers4

1

The resolve is an async method . When you call resolve method it will register a callback in the callback queue and wait for the resolve method to complete, once the function is completed it will trigger The callback function.

The Node will not wait for the callback function, and execute the next statements.

To get the logs statement is sequence and the updated value of the internetConnection variable. include the last console statement inside the callback.

Example.

var internetConnection = "0"
// Checking the internet connection at the start 
require('dns').resolve('www.google.com', function (err) {
  if (err) {
    internetConnection = "1"
    console.log("Internet connection  NO", internetConnection)
  } else {
    internetConnection = "0"
    console.log("Internet connection  yes ", internetConnection)
  }
  console.log("Internet connection  test", internetConnect
});

Or you could wrap it in a promise object.

const dns = require('dns');

function connectionTest() {
  return new Promise((resolve, reject) => {
    dns.resolve('www.google.com1', function (err) {
      if (err) {
        let connectionStatus = 1;
        console.log("Internet connection  NO", connectionStatus)
        reject(connectionStatus);
      } else {
        let connectionStatus = 0;
        console.log("Internet connection  yes ", connectionStatus)
        resolve(connectionStatus);
      }
    });
  });
}

(async function() {
  try {
    internetConnection = await connection();
    console.log("Internet connection  test", internetConnection);
  } catch (error) {
    internetConnection = error
    console.log("Internet connection  test", internetConnection);
  }
})();




Sohail Ashraf
  • 10,078
  • 2
  • 26
  • 42
1

I think you are new to Nodejs, Most of the Nodejs API is async so you are getting that behavior.

console.log("Internet connection  test",internetConnection)

the above statement will be executed even before DNS query resolve. you can try below code snippet

  var {promisify} = require('util');
  var  internetConnection ="0"
  const dns =  require('dns');
  const resolve= promisify(dns.resolve);
  async function testConnection() { 
  try {
        let res= await resolve('www.google.com')
         console.log(res);
         internetConnection="1"
         console.log("Internet connection  yes ",internetConnection)
         return 1;
     }

     catch (err) {
       internetConnection="0"
       console.log("Internet connection NO ",internetConnection)
       return 0
     }
    }


    testConnection().then(function(result){
    console.log("Internet connection  test",result)
  })

Or simply put the console.log("Internet connection test", internetConnect)) statment inside callback function

var internetConnection = "0"
// Checking the internet connection at the start 
require('dns').resolve('www.google.com', function (err) {
  if (err) {
    internetConnection = "1"
    console.log("Internet connection  NO", internetConnection)
  } else {
    internetConnection = "0"
    console.log("Internet connection  yes ", internetConnection)
  }
   console.log("Internet connection  test", internetConnect))
});

check this out for demo:https://repl.it/@sandeepp2016/BeigeCriticalKey

Sandeep Patel
  • 4,815
  • 3
  • 21
  • 37
  • 1. thanks a lot for your answer. It does work as a stand alone app, but when I try to integrate it in the bigger app I get the same behaviour ! – Engine Mar 11 '20 at 08:22
  • Again it could be because of async execution of a program. You will have to think of control flow. Try to learn more about `promises` and `async-await` pattern. – Sandeep Patel Mar 11 '20 at 08:37
0

I am no expert in javascript, but to me it looks like you are resolving a promise when checking the internet connection. As such, the log statement in the last line could be executed before the promise gets resolved. In that case the variable still has its initial value.

Rob
  • 7,320
  • 2
  • 10
  • 9
  • HI Rob, thanks for your answer, is there a solution for it ? – Engine Mar 11 '20 at 06:50
  • You can execute the log statement within a „then“ statement you append to the async resolve call. This would get executed after the promise is resolved. – Rob Mar 11 '20 at 06:52
  • well the problem is that I need this value for the rest of the application , and I need the correct value – Engine Mar 11 '20 at 06:54
  • You will have to `await` the resolution of the promise. Maybe this answer can shed some light into how to do this. https://stackoverflow.com/questions/28921127/how-to-wait-for-a-javascript-promise-to-resolve-before-resuming-function – Rob Mar 11 '20 at 06:59
0

It's because this block of your code is asynchronous:

...
require('dns').resolve('www.google.com', function(err) {
   //handle callback
});
...

Node.js won't wait for it to process, so it continues and run the other line of your code until your promise resolved.

Mostafa Fakhraei
  • 3,409
  • 3
  • 11
  • 25