[Solved] How to detect whether function return value discarded or not?


Tl;dr Schedule a microtask

The point being that using await schedules the rest of the function as a microtask.

Please note that this answer don’t attempt in any way to detect whether a value has been discarded or not. This is solely in answer to the first paragraph (Use-case), dropping the need for the both static code analysis and run-time source code parsing.

The purpose is just to yield control to the calling routine.

await nonPromiseValue is the same as await Promise.resolve(nonPromiseValue). It completes “instantly” but still schedules the code after the await expression to run later. So with f = async () => { await 1; 2;} and calling f(); g() the code will first reach await 1 -> sleep f and schedule the rest on the microtask queue -> call g() -> (eventually when the microtask queue gets to it) resume f() continuing with 2

The values from which to what it changes, or whether it does at all, do not make difference.

let onCompleted; // This would be a property of some request object but that's not needed for the demo

function takeHoursToCompute() { console.log('computing'); return 'Done'; }

function takeMinutesToProcess() { console.log('processing'); }

async function f() {
  // We want to see whether the caller sets onComplete. The problem is that it happens only after calling f().
  // However, if we await it (even though it's not a Promise), this will let the calling function finish before continuing here.
  // Note that *at this point* await(onCompleted) would give undefined, but...
  await onCompleted;
  //...but *by now* onCompleted is already what the caller had set.
  
  const result = takeHoursToCompute();
  if(typeof onCompleted === 'function') {
    // non-Promised call
    takeMinutesToProcess();
    onCompleted(result);
  } else
    console.log('skipping processing');
  
  return result; // returns Promise (because async)
}

window.addEventListener('DOMContentLoaded', () => { // calling code
/* Don't call both branches, because I don't clear onComplete anywhere and that would break the purpose. */
if(true) {

// callback style
  f();
  onCompleted = result => document.getElementById('result').textContent = result;

} else {

  // async style
  (async() => {
    document.getElementById('result').textContent = await f();
  })();

}
});
Result: <span id="result"></span>
<br>
See the console too!

Credits: @TheVee & @Vlaz

solved How to detect whether function return value discarded or not?