Extracting callbacks into separate functions is just more indirection.
And they don't solve the core issue of async control flow that async/await solves, so it's not an alternative to async/await much less a superior one.
A classic example is when you want to conditionally do something asynchronously like B() in this case.
function process(id, callback) {
A(id, (result) => {
if (result === 3) {
B(() => {
C(result, callback);
});
} else {
C(result, callback);
}
});
}
Versus:
async function process(id) {
const result = await A(id);
if (result === 3) {
await B();
}
return C(result);
}
Add a couple more layers of this and the async/await function stays simple and flat, and the callback version grows significantly more complex and nested.