Jump to content
  • Hello visitors, welcome to the Hacker World Forum!

    Red Team 1949  (formerly CHT Attack and Defense Team) In this rapidly changing Internet era, we maintain our original intention and create the best community to jointly exchange network technologies. You can obtain hacker attack and defense skills and knowledge in the forum, or you can join our Telegram communication group to discuss and communicate in real time. All kinds of advertisements are prohibited in the forum. Please register as a registered user to check our usage and privacy policy. Thank you for your cooperation.

    TheHackerWorld Official

javascript 执行机制(同步、异步、微任务、宏任务)

 Share


KaiWn

Recommended Posts

一、关于javascript
JS是一门单线程语言,这意味着所有的任务都需要排队,前一个任务结束才会执行后一个任务如果前一个任务耗时很长,后一个任务就不得不一直等着。
这样所导致的问题是: 如果 JS 执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。

 

二、同步任务和异步任务
单线程导致的问题就是后面的任务等待前面任务完成,如果前面任务很耗时(比如读取网络数据),后面任务不得不一直等待。
为了解决这个问题,利用多核 CPU 的计算能力,HTML5 提出 Web Worker 标准,允许 JS 脚本实现“多个线程”(JS是单线程这一核心仍未改变。所以一切"多线程"都是用单线程模拟出来的),但是子线程完全受主线程控制。于是,JS 中出现了同步任务和异步任务。

1.同步任务
同步任务:在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务。
比如有五个顾客来到了你的饭店,同步的做法是:先给第一个顾客点菜,然后做菜,结束后再给第二个人…以此类推。

2.异步任务
异步任务:不进入主线程、而进入”任务队列”的任务,当主线程中的任务运行完了,才会从”任务队列”取出异步任务放入主线程执行。
比如有五个顾客来到了你的饭店,异步的做法是:先给每一个顾客点菜,点完之后给他们一个牌子并把对应的菜单放到后厨然后让他们等待,之后后厨根据他们的菜单开始做菜。

 

三、微任务和宏任务
异步任务又分为微任务和宏任务。

1.微任务
包括Promise,process.nextTick

Promise(async/await) => Promise并不是完全的同步,在promise中是同步任务,执行resolve或者reject回调的时候,此时是异步操作,会先将then/catch等放到微任务队列。当主栈完成后,才会再去调用resolve/reject方法执行

process.nextTick (node中实现的api,把当前任务放到主栈最后执行,当主栈执行完,先执行nextTick,再到等待队列中找)

MutationObserver (创建并返回一个新的 MutationObserver 它会在指定的DOM发生变化时被调用。)

2.宏任务
包括整体代码script,setTimeout,setInterval

定时器

事件绑定

ajax

回调函数

Node中fs可以进行异步的I/O操作

 

四、执行顺序
执行顺序总结:先做同步任务,在做异步任务,异步任务又分为微任务和宏任务,先做微任务在做宏任务。
同步任务 => 异步任务( 微任务 => 宏任务 )
需要知道的是JS是单线程的,他的异步编程仅仅是根据某些机制来管控任务的执行顺序,所以并不存在同时执行两个任务这一说法。

 

五、示例

console.log("同步任务1");

function workFun(mac) {
    console.log("同步任务2");
    if (mac) {
        console.log(mac);
    }
    return new Promise((resolve, reject) => {
        console.log("Promise中的同步任务");
        resolve("Promise中回调的异步微任务")
    })
}
setTimeout(() => {
    console.log("异步任务中的宏任务");
    setTimeout(() => {
        console.log("定时器中的定时器(宏任务)");

    }, 0)
    workFun("定时器传递任务").then(res => {
        console.log('定时器中的:', res);
    })
}, 0)
workFun().then(res => {
    console.log(res);
})
console.log("同步任务3")

/*
** 同步任务1 
同步任务2
Promise中的同步任务
同步任务3
Promise中回调的异步微任务

异步任务中的宏任务
同步任务2
定时器传递任务
Promise中的同步任务
定时器中的: Promise中回调的异步微任务
定时器中的定时器(宏任务)
*/

 

Link to post
Link to comment
Share on other sites

 Share

discussion group

discussion group

    You don't have permission to chat.
    • Recently Browsing   0 members

      • No registered users viewing this page.
    ×
    ×
    • Create New...