1 JS是单线程
js是单线程的。也就是说,同一个时间只能做一件事。作为浏览器脚本语言,与它的用途有关。JavaScript的主要用途是和用户互动,以及操作DOM,这决定了它只能是单线程。
js是单线程的。也就是说,同一个时间只能做一件事。有些任务是耗时的,会阻塞代码的执行。
我们可以把代码分为同步代码(同步任务)和异步代码(异步代码):
同步代码:立即放入JS引擎(JS主线程)执行,并原地等待结果。
异步代码:先放入宿主环境(浏览器/Node),不必原地等待结果,并不阻塞主线程继续往下执行,异步结果在将来执行。
1、JS是单线程,防止代码阻塞,我们把代码(任务):同步和异步
2、同步代码给js引擎执行,异步代码交给宿主环境
3、同步代码放入执行栈中,异步代码等待时机成熟送入任务队列排队
4、执行栈执行完毕,会去任务队列看是否有异步任务,有就送到执行栈执行,反复循环查看执行,这个过程是事件循环(eventloop)。
2 宏任务和微任务
JS把异步任务分为宏任务和微任务。在ES5之后,JavaScript引入了Promise,这样,不需要浏览器,JavaScript引擎自身也能够发起异步任务了。宏任务是由宿主(浏览器、Node)发起。微任务JS引擎发起的任务。Promise本身同步, then/catch的回调函数是异步的。
代码可能有3种:
1、同步代码(js 执行栈)
2、微任务的异步代码(js引擎)
process.nextTick ( node)
Promise.then() catch()
Async/Await
Object.observe等等
3、宏任务的异步代码(宿主环境)
script (代码块)
setTimeout / setInterval定时器
setlmmediate定时器
以下代码的执行过程:https://www.jsv9000.app/
console.log(1)
setTimeout(function () {
console.log(2)
}, 0)
const p = new Promise((resolve, reject) => {
console.log(3)
resolve(1000)
console.log(4)
})
p.then(value => {
console.log(value)
})
console.log(5)
https://www.jsv9000.app/?code=Y29uc29sZS5sb2coMSkNCnNldFRpbWVvdXQoZnVuY3Rpb24gKCkgew0KICAgIGNvbnNvbGUubG9nKDIpDQp9LCAwKQ0KY29uc3QgcCA9IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0%2BIHsNCiAgICBjb25zb2xlLmxvZygzKQ0KICAgIHJlc29sdmUoMTAwMCkNCiAgICBjb25zb2xlLmxvZyg0KQ0KfSkNCnAudGhlbih2YWx1ZSA9PiB7DQogICAgY29uc29sZS5sb2codmFsdWUpDQp9KQ0KY29uc29sZS5sb2coNSk%3D
1 举例说明-1
结果执行顺序为 : 3 2 1
2 举例说明-2
输出结果为:11 14 12 15 13
3 举例说明-3
输出结果为 :2 3 6 p2 p1 1 4 5
4 举例说明-4 字节跳动的问题
async function async1() {
console.log('async1');
await async2();
console.log('async1 end');
}
async function async2() {
console.log('async2');
}
console.log('script start');
setTimeout(function () {
console.log('setTimeout');
}, 0);
async1();