0

I have a function which return a promise getPort() from the npm package https://www.npmjs.com/package/get-port.

I need to change this one so I can stop the code until I don't have the value. like:

var port = getPortSync()

I can't use generators or await / async cuz the code is actually not in a function.

Basically, I want to do something like readFileSync in node.

The reason I'm doing this is that I have a bunch of mocha tests where the variable are declared on the top of the file, I need to retrieve the free port value before the declaration/ initialization of those variables and I want to change the minimum number of lines.

My current attempt is:

var getPortSync = function() {
  var port = null
    getPort().then(function(freePort) {
      console.log('port', freePort)
      port = freePort
    })
    while (port === null) {
      console.log('port: ', port)
    }
    return port
  }
2
  • 2
    Two questions: first, why not just do the Mocha tests inside the then of the returned promise? Second, does your attempt work? Commented Feb 2, 2017 at 15:16
  • sorry, I forgot to mention that it is not working. I put it just to give an idea of what I need. Commented Feb 2, 2017 at 17:43

1 Answer 1

4

Unfortunately, your approach is not possible.

The code you have there will always have an infinite loop because the assignment of the port happens asynchronously and a while loop is a synchronous construct.

If you open the code from the package, the way it is obtaining the port is via an asynchronous callback:

server.listen(0, function () {
  var port = server.address().port;
  // ...
});

The main part of the code, server.address(), will only have the port information after the server emits the listening event, which means there isn't a way to obtain this synchronously.

Perhaps you can wrap the test in the then of the promise?

getPort().then((port) => {
  // your test code
});

You could also use mocha's test hooks (which work great with promises) to obtain the port before a test block:

describe('my-test', function() {

  let port;
  before(() => getPort().then((p) => {
    port = p;
  });

Or if you know the port or it's always the same, perhaps you could just hard code it in the test.

Sign up to request clarification or add additional context in comments.

3 Comments

You can also just hold on to the promise. let portPromise; before(() => portPromise = getPort()). Then, in your tests, you would start out with portPromise.then((port) => { ... }).
basically, the port WAS always the same, but it is used to spin up the server. So right now my tests work if you run them alone, but not if you run them together!. We don't want a random number to avoid collision, and we don't want to change them manually for every test. The approach you suggested (moving the code inside the .then) is what I'm doing now, but it is long and I was trying to find a way to avoid it :)
@jurgo yeah, unfortunately you have to work around javascript's async nature. Async/await would probably give the cleanest looking code as in it would look almost synchronous but since you cannot use it, the only other approach is through promises directly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.