进程与线程

进程(process):程序的一次执行,占有独有的一片内存空间;可以通过windows任务管理器查看进程。

线程(thread):是进程内的一个独立执行单元,是程序执行的一个完整流程,是CPU最小的调度单元。

  • 一个进程内只有一个线程的程序,就是单线程程序;
  • 一个进程中可以同时运行多个线程,称为多线程程序;
  • 应用程序必须运行在某个进程的某个线程上;
  • 一个进程中至少有一个运行的线程:主线程,是进程启动后自动创建的
  • 一个进程内的数据可供其中的多个线程直接共享
  • 多个进程之间的数据是不能直接共享的(互相独立)

多线程的优点:能有效提高cpu的利用率;缺点:创建多线程开销;线程间切换开销;状态同步问题。

单线程优点:顺序编程简单;缺点:效率低。

  • Chrome,Safari:webkit
  • Firefox:Gecko
  • IE:Trident

JavaScript事件循环机制

JavaScript的一大特点是单线程,这个线程中有唯一的一个事件循环。

这个事件循环中会有一个正在执行的任务(Task),而这个任务就从macrotask队列中来的。当这个macrotask队列中的任务执行结束后会取出microtask中的任务,然后在同一个事件循环中执行。

  • macrotasks: setTimeoutsetInterval、I/O等
  • microtasks: Promise

一些注意点:

  • 一个事件循环(event loop)会有一个或多个任务队列(task queue),任务队列就是macrotask queue
  • 每一个event loop都有一个microtask queue
  • task queue == macrotask queue != microtask queue
  • 事件循环的顺序,决定了JavaScript代码的执行顺序。从整体代码开始第一次循环。从macrotask开始,执行完macrotask再执行microtask,当所有的microtask执行完毕之后再次从macrotask开始,这样一直循环下去。

分析一段代码:

console.log('start')

setTimeout(() => {
    console.log('setTimeout 1')
    Promise.resolve()
    .then(() => {
        console.log('promise 3')
    })
    .then(() => {
        console.log('promise 4')
    })
    .then(() => {
        setTimeout(() => {
            console.log('setTimeout 2')
            Promise.resolve()
            .then(() => {
                console.log('promise 5')
            })
            .then(() => {
                console.log('promise 6')
            })
        }, 0)
    })
}, 0)

Promise.resolve()
.then(() => {  
    console.log('promise 1')
})
.then(() => {
    console.log('promise 2')
})

// 运行结果
// start
// promise 1
// promise 2
// setTimeout 1
// promise 3
// promise 4
// setTimeout 2
// promise 5
// promise 6

对这段代码进行一下分析:

  • loop1

    • setTimeout的回调(setTimeout 1)进入macrotask
    • promise的两个then进入microtask(promise 1 和 promise 2)
    • 当前执行环境执行结束,开始执行microtask queue,输出promise 1 和 promise 2
  • loop2

    • 先执行macrotask,先输出setTimeout 1
    • 接下来的三个promise进入microtask,当前执行环境已空,则执行microtask,输出promise 3 和 promise 4,第三个promise(setTimeout 2)又一次进入了macrotask queue
  • loop3

    • 同样,macrotask,输出setTimeout 2,两个promise的then进入microtask
    • 执行microtask,输出promise 5 和 promise 6

results matching ""

    No results matching ""