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?