as JS is supposedly a non-blocking, asynchronous driven language
No, it isn't. But we commonly use it in environments that lean toward asynchronicity. JavaScript is fundamentally just like any other language, code progresses synchronously step by step. The only asynchronous thing about JavaScript itself, as opposed to the environments in which we run it, is promises and the syntax around them such as async
/await
.
If you want to make your sort call asynchronous in relation to the trigger, you were right to look at promises:
sortColumn(): void {
this.sortOrder = !this.sortOrder;
Promise.resolve().then(() => {
this.service.someExpensiveBlockingOperation();
this.data.sort((a, b) => { ... });
});
}
There I've put the flag flip in the synchronous code, and everything else in the asynchronous callback. The then
callback is guaranteed to be called asynchronously.
You could also use setTimeout
sortColumn(): void {
this.sortOrder = !this.sortOrder;
setTimeout(() => {
this.service.someExpensiveBlockingOperation();
this.data.sort((a, b) => { ... });
}, 0);
}
In an ES2015+-compliant environment, the then
callback would be called sooner than the setTimeout
callback, because promise callbacks are "microtasks" run immediately after the macrotask where they were scheduled was completed, whereas a setTimeout
callback is a macrotask. In practice, it's rarely relevant (but is, sometimes).