Użycie callbacka sprawia, że metoda crypto.randomBytes działa asynchronicznie. W związku z tym, nie możesz zwrócić z niej wartości (drugi przykład/kod). W pierwszym przypadku tworzysz zmienną, która ma zasięg w obrębie callbacka, stąd nie widać jej na zewnątrz.
Przy podejściu asynchronicznym możesz wspomóc się Promisem:
new Promise((resolve, reject) => {
crypto.randomBytes(16, (err, buf) => {
if (err) reject(err);
resolve(buf.toString('hex') + path.extname(req.file.originalname));
})
}).then(fileName => console.log(fileName));