JavaScript异步编程白话

JavaScript(JS)本质上是单线程的,这意味着在任何时候,JavaScript引擎只能执行一个任务(或称作一个执行上下文)。这个特性决定了JS程序不能同时执行多个操作,特别是对于CPU密集型计算,它们必须按照顺序逐个执行。然而,尽管JS本身是单线程的,但它通过异步编程模型实现了并发效果,这种并发并非并行(parallelism),而是并发(concurrency),即任务之间看似同时发生但实际上在单线程中交错执行。

单线程限制与优势:

  • 限制:由于只有一个执行线程,JS无法真正意义上同时处理多个任务。这意味着,当一个任务正在执行时,其他任务必须等待,尤其是那些耗时的操作(如网络请求、文件读写、长时间计算等),如果同步执行,将会阻塞主线程,导致用户界面无响应(UI freeze)。

  • 优势:单线程简化了编程模型,避免了多线程编程中常见的复杂问题,如竞态条件(race conditions)、死锁(deadlocks)和资源同步。对于浏览器环境而言,这种设计有利于保护共享状态(如DOM),防止因多线程并发访问导致的混乱。

异步编程与事件循环:

  • 异步编程:为了克服单线程带来的阻塞性,JavaScript采用了异步编程模型。异步操作(如网络请求、定时器、事件监听等)不会立即得到结果,而是会在未来某个时刻完成。JS提供了回调函数、Promise、async/await等机制来处理这些操作的结果,使得代码可以在不阻塞主线程的情况下等待异步任务完成。

  • 事件循环:JavaScript实现异步并发的核心是事件循环(Event Loop)。事件循环是一个持续运行的机制,它负责管理任务队列(Task Queue)和微任务队列(Microtask Queue),并按特定规则调度这些任务的执行。

异步编程介绍:

同步任务:

console.log(123);
 
console.log(456);
 
for (let i = 1; i <= 5; i++) {
 
  console.log(i);
 
}
 

这里一定是先输出123,再输出456,本质就是顺序执行。

异步任务:

setTimeout(() => {
 
  console.log('定时器');
 
}, 0)
 
console.log('奥特曼');
 

setTimeout(() => { console.log('定时器'); }, 0) console.log('奥特曼');

按普通的执行顺序来说,定时器在上面 ,应该先输出定时器,再输出奥特曼

最后拿到的结果却先输出奥特曼 在输出了定时器 原因呢就是 setTimeout是异步任务。

对于宏任务和微任务 可以理解为两种异步的形态,异步有两个孩子宏任务和微任务。

宏任务中的方法:1. script (可以理解为外层同步代码,作为入口 ) 2. setTimeout/setInterval

微任务中的方法:1.Promise 2. nextTick

而他们的执行顺序是先输出微任务,再输出宏任务。

事件循环介绍:

由上文可知,先同步,再异步,异步中,先微任务,再宏任务。

如下代码的输出能体现出这个规则:

setTimeout(() => {
 
  console.log('定时器');
 
}, 0)
 
new Promise((resolve) => {
 
  console.log('同步代码') 
 
  resolve('异步代码')
 
}).then((res) => {
 
  console.log(res);  
 
})
 
console.log('奥特曼');

注意,new Promise是创建一个构造函数,这个过程是同步的,而.then方法是异步的。

顺序图如下:

执行栈:

(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。

(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。

(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件,于是那些对应的异步任务结束等待状态,进入执行栈,开始执行。

(4)主线程不断重复上面的第三步,称为事件循环(Event Loop)。

生动实例:

  • 11
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值