Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[2019-03-08]: Event Loop #13

Open
Lemonreds opened this issue Mar 8, 2019 · 0 comments
Open

[2019-03-08]: Event Loop #13

Lemonreds opened this issue Mar 8, 2019 · 0 comments

Comments

@Lemonreds
Copy link
Owner

什么是 Event Loop

JavaScript是单线程语言,为了避免多线程对同一DOM进行操作时带来的同步问题。单线程意味着一个时刻只能做一件事情,当一段代码很耗时时,就会造成堵塞,代码长时间卡死。为此,JavaScript将任务划分成同步任务和异步任务,所有的同步任务都放置到主线程执行栈中进行(同步任务的优先级是最高的),而主线程之外,还有一个事件队列,异步任务有了处理结果后,就会将其回调函数入栈,等待调用。一但所有的同步任务执行完毕后,主线程就会读取事件队列,将完成的回调函数放入执行栈中执行。接着继续读取事件队列的回调函数执行,周而复始,直到所有事件都执行完毕。

宏任务和微任务

事件队列又再次细分,分为宏任务队列如 setTimeout和微任务队列如 promise,主线程执行完所有的微任务后,才会去执行宏任务队列,微任务队列的优先级是高于宏任务队列的、同时每一个宏任务执行前,浏览器都会对网页进行渲染。

例子

    console.log('start')
    setTimeout(() => {
        console.log('setTimeout')
    }, 0)
    Promise.resolve().then(() => {
        console.log('promise1')
    })
    let promise2 = new Promise((resolve) => {
        resolve()
        console.log('promise2')
    }).then(() => {
        Promise.resolve().then(() => {
            console.log('promise3')
        })
    })
    console.log('end')
  1. 执行同步代码输出 start
  2. 将setTimeOut的回调加入宏任务队列
  3. 将Promise1的回调加入微任务队列
  4. 执行同步代码 输出 promise2
  5. 将promise2回调加入微任务队列
  6. 执行同步代码end,此时同步代码执行完毕
  7. 执行微任务队列,输出promise1,将p3回调加入到微任务队列
  8. 输出promise3 微任务队列执行完毕
  9. 执行宏任务队列,输出setTimeout
async function a1() {
    console.log('a1 start')
    await a2()
    console.log('a1 end')
}
async function a2() {
    console.log('a2')
}
console.log('start')
setTimeout(() => {
    console.log('setTimeout')
}, 0)
Promise.resolve().then(() => {
    console.log('promise1')
})
a1()
let promise2 = new Promise((resolve) => {
    resolve()
    console.log('promise2')
}).then(() => {
    Promise.resolve().then(() => {
        console.log('promise3')
    })
})
console.log('end')
  1. 执行同步任务,输出start,将setTimeout回调加入到宏任务队列。
  2. 将promise1回调加入到微任务队列。
  3. 执行async a1() 输出 a1 start ,遇到await表达式,执行 async a2()输出a2。
  4. 跳出 async 函数执行外面的同步代码。
  5. 执行同步代码,输出promise2,将promise2的回调加入到微任务队列。
  6. 执行同步代码,输出end,此时同步代码执行完毕。
  7. 执行微任务队列,输出 promise1, 将promise3的回调加入到微任务队列。
  8. 输出promise3,执行微任务队列完毕。
  9. 回到aysnc a1 继续执行,输出 a1 end。
  10. 执行宏任务队列,输出 setTimeout.

当await后面跟一个Promise时(async函数无返回值时,会返回Promise.resolve(undefined)),会等待到微任务队列执行完毕后执行后面"阻塞"的代码。

TODO

async/await 原理。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant