0

I have the following function from another SO answer that fetches a local IP address. I output the local IP twice, once in the function, and I also try to output the value where the function is called:

function getLocalIP () {
  window.RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection
  var pc = new RTCPeerConnection({iceServers: []})
  var noop = function () {}
  var localIP

  pc.createDataChannel('')
  pc.createOffer(pc.setLocalDescription.bind(pc), noop)
  pc.onicecandidate = function (ice) {
    if (!ice || !ice.candidate || !ice.candidate.candidate) return
    localIP = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/.exec(ice.candidate.candidate)[1]
    console.log(localIP)
  }
  return localIP
}

console.log(getLocalIP())

This outputs:

undefined
192.168.0.1

I mostly understand why this is happening. JavaScript is asynchronous so getLocalIP is returning the value when it is still undefined.

How can I work with this to get the behaviour I expect from a synchronous background? I come from a Python background where I would expect the code above to return the defined variable.

Juicy
  • 9,942
  • 32
  • 97
  • 181
  • Your code would produce the same output in Python. – melpomene May 25 '18 at 16:22
  • `pc.onicecandidate` is never called – J. Pichardo May 25 '18 at 16:22
  • Presumably, `onicecanditate` is an asynchronous operation. Therefore, `localIP` is `undefined` at the end of `getLocalIP()` and is only logged when the `onicecandidate` handler is run. – Kevin Boucher May 25 '18 at 16:23
  • JS is synchronous, all code runs in sequence. Setting a property to a callback function, passing a callback function is not the same as executing said callback. – Patrick Evans May 25 '18 at 16:24
  • 1
    @J.Pichardo `onicecandidate` must be called automatically by the RTC code. – Barmar May 25 '18 at 16:24
  • @melpomene not really the same situation yeah because of how `oneicecandidate` gets called automatically, but if I define and run a child function within a parent function in Python, it won't return before the child function completes. – Juicy May 25 '18 at 16:36
  • @Juicy If you define and run a nested function within a function in JavaScript, it won't return before the inner function completes either. The whole point is that `getLocalIP` never calls the `onicecandidate` function, it just registers it as a callback. Which behaves exactly the same way in Python and JS. – melpomene May 25 '18 at 16:46
  • I guess we’ve established that you don’t return values from asynchronous functions. But you’re free to consume them (as you’re doing above) in the callback function. Now take the example a step further, and pass in your own function foo to getLocalIp. The function foo() is called from onicecandidate, and we’ve setup a nice chain of asynchronous callbacks. Unfortunately, all this leads to maintenance nightmares. And that’s where Promises come in. If you haven’t already, read up. – Timir May 25 '18 at 17:05

0 Answers0