Event Loop总结

首先,明确浏览器是多线程的,而js是单线程,至于为什么是单线程,阮一峰大神的博客是这么说的:

原因大概是不想让浏览器变得太复杂,因为多线程需要共享资源、且有可能修改彼此的运行结果,对于一种网页脚本语言来说,这就太复杂了。后来就约定俗成,JavaScript为一种单线程语言。(Worker
API可以实现多线程,但是JavaScript本身始终是单线程的。)

请添加图片描述

其次,明确Event Loop是一个程序结构,译为事件循环,用于等待和发送消息和事件,主要是连接主线程与负责主线程与其他进程(主要是各种I/O操作)的通信。

再次,明确JavaScript的单线程是主线程+调用栈(即执行栈),主线程负责执行,调用栈将同步任务按照顺序交与主线程执行,异步任务会在调用返回结果后,将注册的回调函数放入任务队列中等待主线程空闲的时候(调用栈被清空),被读取到栈内等待主线程的执行​。
请添加图片描述
再次,明确调用栈中有两种任务:宏任务、微任务。

  • 宏任务:script, settimeout,ajax请求,dom事件;
  • 微任务:Promise.then、MutationObserver、process.nextTick();

​个人理解,宏任务就是不需要等待返回结果,在此期间可以做别的操作的任务;微任务就是必须等待结果返回才能进行下一步操作的任务。

需记住:同一事件循环中,微任务永远在宏任务之前。

当宏任务执行完,执行栈空闲时,js首先会将微队列中的所有微任务执行完,再去执行宏队列中的宏任务。如此反复,就是事件循环了。

一轮循环是这样的:是一次宏任务加上当前所有微任务执行。当js执行时,先执行宏任务(其实,就是当前宏任务中所有的同步任务),遇到微任务,则推入微队列,并注册回调函数。当该次宏任务执行完后,会读取微任务注册的回调函数到执行栈中执行。执行完后。继续下一轮循环。

例子1:

setTimeout(function () {
  console.log('three');
}, 0);

Promise.resolve().then(function () {
  console.log('two');
});

console.log('one');
结果:
// one
// two
// three

例子2:

console.log('1');
setTimeout(function () {
    console.log('2');
    process.nextTick(function () {
        console.log('3');
    })
    new Promise(function (resolve) {
        console.log('4');
        resolve();
    }).then(function () {
        console.log('5')
    })
})
process.nextTick(function () {
    console.log('6');
})
new Promise(function (resolve) {
    console.log('7');
    resolve();
}).then(function () {
    console.log('8')
})

setTimeout(function () {
    console.log('9');
    process.nextTick(function () {
        console.log('10');
    })
    new Promise(function (resolve) {
        console.log('11');
        resolve();
    }).then(function () {
        console.log('12')
    })
})

结果:
// 1
// 7
// 6
// 8
// 2
// 4
// 3
// 5
// 9
// 11
// 10
// 12
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这个报错表明你的代码正在尝试使用当前事件循环,但是没有检测到当前事件循环。这通常是因为你的代码正在尝试使用 `asyncio` 库,但是没有设置事件循环。 要解决这个问题,你需要在你的代码中设置事件循环。你可以使用 `asyncio.AbstractEventLoop.run_until_complete` 来设置事件循环,并在需要的地方调用它。 例如: ``` import asyncio async def my_task(): print("Hello, World!") loop = asyncio.get_event_loop() loop.run_until_complete(my_task()) loop.close() ``` 这样就能解决这个报错。 ### 回答2: DeprecationWarning: There is no current event loop 是Python代码中常见的警告信息,通常出现在使用asyncio库时没有设置当前的事件循环。要解决这个报错,可以采取以下两种方法: 1. 在异步代码块中设置当前事件循环。可以使用以下代码来创建并设置事件循环: ``` import asyncio loop = asyncio.get_event_loop() # 在此处编写异步代码 ``` 使用上述代码将获取并设置一个事件循环,然后在获取事件循环后进行异步操作。 2. 使用`asyncio.run()`方法包装主函数。 ``` import asyncio async def main(): # 在此处编写异步代码 asyncio.run(main()) ``` `asyncio.run()`是在Python 3.7中引入的方法,用于运行异步函数。它将自动创建一个新的事件循环,并将主函数封装在其中。使用这种方法可以简化代码,避免手动设置事件循环的繁琐过程。 总结来说,要解决DeprecationWarning: There is no current event loop的报错,可以设置当前事件循环或使用asyncio.run()方法包装主函数。当然,在实际开发过程中,还需要根据具体情况进行适当的异步编程调整,以充分利用asyncio库的功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值