Browser - web api's (DOM, ajax, setTimeout...)
Node.js - bindings (file-system, network, other...)
for( let i = 0 ; i < 1000000000 ; i++ ) {
//nothing will run until this loop ends…
}
const now = new Date().getTime();
while (new Date().getTime() < now + 10000){
//the thread is blocked for 10 seconds…
}
The Call Stack is single threaded
async io calls run in other threads
Then added to the callback queue
Then executed in the stack once it is available
How can we make sure those will not to block the call stack?
We can break down a long process to small "async"
chunks and use setTimeout() to avoid blocking
function longProcess(array,render){
const items = [...array]; //clone the array
const iterator = ()=> {
const item = items.shift();
render(item);
if (items.length > 0) setTimeout(iterator, 0);
}
setTimeout(iterator, 0);
}
Between each process, we call setTimeout with 0 milliseconds delay,
giving the call stack a chance to execute and clear
If the call-stack is not empty, it will finish running the code first
and only then process the callback queue…
So we can use setTimeout(func,0) to breakdown
long JS computation into small non-blocking operations
setTimeout(func,0)
The recommended way is to use setImmediate(func);
suggested by Microsoft and implemented by Node.js
setImmediate(func)
for all browsers and old 0.9 Node.js
Shim - setImmediate demo
So when breaking up a long running job using an iterator,
you want to use setImmediate rather than process.nextTick
otherwise any I/O callbacks wouldn't get the chance to run between iterations.
What will we see in the console?
setTimeout( ()=> console.log('hello') , 0);
[...'world'].map( str => console.log(str) );
console.log('!');
console.log('Kick-off');
setTimeout(()=> console.log('timeout') , 0);
Promise.resolve()
.then(()=> console.log('promise 1') )
.then(()=> console.log('promise 2') )
.then(()=> console.log('promise 3') )
console.log('The end!');
console.log('Kick-off');
setImmediate(()=> console.log('setImmediate'));
Promise.resolve()
.then(()=> console.log('promise 1') )
.then(()=> console.log('promise 2') )
.then(()=> console.log('promise 3') )
console.log('The end!');
console.log('Kick-off');
process.nextTick(()=> console.log('nextTick'));
Promise.resolve()
.then(()=> console.log('promise 1') )
.then(()=> console.log('promise 2') )
.then(()=> console.log('promise 3') )
console.log('The end!');