Properly call callback on a node server on the listening or error event.
Why?
I continue to see the following:
const http = require('http')
const server = http.createServer()
server.listen((err) => { // `err` won't be passed here
if (err) throw err
})
The problem with that is that the cb
passed to the listen
function is
only added as an event listener for the listening
event.
i.e. no err
will ever be passed back.
In order to properly wait for either the listening event or error event without leaking listeners:
function doListen(server, cb) {
var called = false
const done = (err) => {
if (called) return
server.removeListener('error', done)
server.removeListener('listening', done)
called = true
cb(err)
}
server.on('error', done)
server.on('listening', done)
}
which is literally what the package is :]
$ npm install do-listen
'use strict'
const net = require('net')
const doListen = require('do-listen')
const server = net.createServer()
server.listen(0)
doListen(server, (err) => {
if (err) throw err
console.log('listening on', server.address().port)
})
This also works with http
'use strict'
const http = require('http')
const doListen = require('do-listen')
const server = http.createServer()
server.listen(8080)
doListen(server, (err) => {
if (err) throw err
console.log('listening on', server.address().port)
})
Want to use with promises or async/await?
'use strict'
const http = require('http')
const {promisify} = require('util')
const doListen = promisify(require('do-listen'))
const server = http.createServer()
server.listen(8080)
async function main() {
await doListen(server)
}
main()
// or
'use strict'
const http = require('http')
const {promisify} = require('util')
const doListen = promisify(require('do-listen'))
const server = http.createServer()
server.listen(8080)
doListen(server).then(() => {
console.log('listening on', server.address().port)
}).catch((err) => {
throw err
})
$ npm test
Evan Lucas
MIT (See LICENSE
for more info)