当前位置: 首页 > news >正文

如何用织梦猫做网站和后台/自媒体

如何用织梦猫做网站和后台,自媒体,app应用程序,webapi做网站事件轮询机制 事件执行顺序: 引入一下两个概念: 宏任务(Macrotasks):就是参与了浏览器事件循环的异步任务 宏任务有:setTimeout,setInterval微任务(Microtasks): 直接…

事件轮询机制

事件执行顺序:

引入一下两个概念:

  1. 宏任务(Macrotasks):就是参与了浏览器事件循环的异步任务
    宏任务有:setTimeout,setInterval
  2. 微任务(Microtasks): 直接在 Javascript 引擎中的执行的,没有参与浏览器事件循环的任务。
    微任务:promise的then,await后面的语句,process.nextTick

执行的顺序是**‘先同后异,先微后宏’**

事件轮询机制阶段:

  • 定时器:本阶段执行已经被 setTimeout() 和 setInterval() 的调度回调函数。
  • 待定回调:执行延迟到下一个循环迭代的 I/O 回调。
  • idle, prepare:仅系统内部使用。
  • 轮询:检索新的 I/O 事件;执行与 I/O 相关的回调(几乎所有情况下,除了关闭的回调函数,那些由计时器和 setImmediate() 调度的之外),其余情况 node 将在适当的时候在此阻塞。
  • 检测:setImmediate() 回调函数在这里执行。
  • 关闭的回调函数:一些关闭的回调函数,如:socket.on(‘close’, …)。

定时器:本阶段执行已经被 setTimeout() 和 setInterval() 的调度回调函数。

会在轮询阶段最后执行

待定回调:执行延迟到下一个循环迭代的 I/O 回调。

系统操作的回调

idle, prepare:仅系统内部使用。

轮询:检索新的 I/O 事件;执行与 I/O 相关的回调(几乎所有情况下,除了关闭的回调函数,那些由计时器和 setImmediate() 调度的之外),其余情况 node 将在适当的时候在此阻塞。

  1. 队列不为空:循环访问回调队列,并同步执行
  2. 队列为空:
  3. 有setImmidiate(cb),结束轮询,到达检查阶段执行setImmidiate的cb
  4. 无setImmidiate(cb),被加入队列,并同步执行事件。

无setImmidiate(cb)举例:

一般情况下是这样

一个的时候:

   new Promise((resolve, reject) => { console.log(1); resolve(2)}).then(data => console.log(data)) 

第一次进入轮询阶段,轮询队列为空 && 无setImmidiate,则then会被加入到队列,console.log(1); resolve(1) 会被执行。then需要等待下次轮询。
到第二次进入轮询阶段,则队列里面有then,则调用then的回调data=>console.log(data)

多个的时候:

new Promise((resolve, reject) => {console.log(1)resolve(2)
}).then(console.log)new Promise((resolve, reject) => {console.log(5)resolve(6)
}).then(data => {console.log(data)new Promise((resolve, reject) => {console.log(7)resolve(8)}).then(console.log)new Promise((resolve, reject) => {console.log(9)resolve(10)}).then(console.log)
})new Promise((resolve, reject) => {console.log(3)resolve(4)
}).then(console.log)console.log(0)

以上很可看出执行顺序是:

第一次轮询:同步:1530进入微任务:6,4,进入下一次轮询进入微任务:8,10

有setImmidiate(cb)举例:

setImmediate(console.log, 0)new Promise((resolve, reject) => {console.log(11)resolve(12)
}).then(console.log)function asyncFn(cb) {setImmediate(cb, 3) 
}
asyncFn(data => {new Promise((resolve, reject) => {console.log(data)resolve(6)}).then(console.log)new Promise((resolve, reject) => {console.log(7)resolve(8)}).then(console.log)
})setImmediate(console.log, 4)new Promise((resolve, reject) => {console.log(13)resolve(14)
}).then(console.log)console.log(5)
同步:1113,5
异步:进入轮询阶段队列不为空,执行回调:12,14队列为空:执行setImmediate
结束轮询
检查阶段:0
进入轮询阶段队列为空
结束轮询
检查阶段:37
进入轮询阶段队列不为空:6,8轮询为空:执行setImmediate
结束轮询
检查阶段:4

这里跟promise的区别就是setImmediate会被轮询任务卡住,只有不为空的情况下才会被执行,其顺序是在每层轮询后才会被执行。

检测:setImmediate() 回调函数在这里执行。

执行回调

关闭的回调函数:一些关闭的回调函数,如:socket.on(‘close’, …)。

如果套接字或处理函数突然关闭(例如 socket.destroy()),则’close’ 事件将在这个阶段发出。否则它将通过 process.nextTick() 发出。

关注的问题:

process.nextTick() vs setImmediate() vs setTimeout()

从功能上来讲,其实setImmidiate的效果是下一次轮询前的执行,即nextTick。而process.nextTick的效果是在轮询阶段执行,刚好是Immediate的意思。这两者的名字应该是调转过来才对。

setTimeout: 最后执行

异步中任务顺序:

setImmediate(console.log, 0)// 关注这两个
setTimeout(console.log, 0, 999) 
setTimeout(console.log, 10, 1000)new Promise((resolve, reject) => {console.log(11)resolve(12)
}).then(console.log)function asyncFn(cb) {setImmediate(cb, 3) 
}
asyncFn(data => {new Promise((resolve, reject) => {console.log(data)process.nextTick(console.log, 119)resolve(6)}).then(console.log)new Promise((resolve, reject) => {console.log(7)process.nextTick(console.log, 229)resolve(8)}).then(console.log)
})setImmediate(console.log, 4)new Promise((resolve, reject) => {console.log(13)resolve(14)
}).then(console.log)
/* 1113533912149990371192296841000
*/

setTimeout是看其阈值情况而定,如果小于其阈值,比如为0,是在一次轮询后立即执行
promise.then = await的下一条语句 > process.nextTick > setTimeout > setImmediate如果大于其阈值,比如设置300,则是多次轮询后,最后执行
promise.then = await的下一条语句 > process.nextTick > setImmediate > ...多轮 > setTimeout

以上就是为什么会在代码中经常看到使用setTimeout(fm, 0)或者setTimeout(fm, 300)的原因。

建议:

  1. 开发人员在所有情况下都使用 setImmediate(),因为它更容易理解

  2. 使用 setImmediate() 相对于setTimeout() 的主要优势是,如果setImmediate()是在 I/O 周期内被调度的,那它将会在其中任何的定时器之前执行,跟这里存在多少个定时器无关

我要注意什么事情?

如果运行以下不在 I/O 周期(即主模块)内的脚本,则执行两个计时器的顺序是非确定性的,因为它受进程性能的约束:
I/O 循环内调用,setImmediate 总是被优先调用:

比如:

setTimeout(() => {console.log('timeout');
}, 0);
setImmediate(() => {console.log('immediate');
});

为什么要使用 process.nextTick()?

有两个主要原因:

  • 允许用户处理错误,清理任何不需要的资源,或者在事件循环继续之前重试请求。

  • 有时有让回调在栈展开后,但在事件循环继续之前运行的必要。

例子1:

const EventEmitter = require('events');
const util = require('util');
function MyEmitter() {EventEmitter.call(this);// 执行构造函数,出发event事件但监听的代码还没执行到,触发的事件并未被监听到,下面的代码不会被执行。// this.emit('event');// 捕获到错误,并加入事件队列放到下次轮询中调用process.nextTick(() => {this.emit('event');})
}
util.inherits(MyEmitter, EventEmitter);
const myEmitter = new MyEmitter(); 
myEmitter.on('event', () => {console.log('an event occurred!');
});

例子2:

const server = net.createServer();
server.on('connection', (conn) => { });
server.listen(8080);
server.on('listening', () => { });

这个例子效果同上,是我们常用常见的写法。其实一般我们会把.on写在事件方式前,提前进行监听,这样才能捕捉到事件

参考:https://www.bookstack.cn/read/nodejs-guide/590a0c76ccf949ba.md#gxvmd

http://www.jmfq.cn/news/5212405.html

相关文章:

  • 焦作做网站/在线推广企业网站的方法有哪些
  • 做调查问卷的网站/上海做关键词推广企业
  • 做演示的网站/海外广告优化师
  • 做团购网站的公司/山东济南最新消息
  • 网站建设销售员工作内容/平台推广渠道
  • 微网站可以做商城吗/总推荐榜总点击榜总排行榜
  • 如何安装织梦做的网站/草根站长工具
  • 制作网站账号系统/友链价格
  • 网站需要哪些备案/seo全网推广
  • 大型公司网站建设/百度一下你就知道首页
  • 如何做网站/做一个私人网站需要多少钱
  • 一个公司可以做几个网站/百度搜索排名规则
  • 国内wordpress有名的网站/如何创建自己的网址
  • 会计软件定制开发包括/西安seo
  • 天津网站建设渠道/长沙网站关键词排名公司
  • 腾讯云做网站选哪个/湖南竞价优化哪家好
  • 代理做网站的合同/国家税务总局网
  • 公众号怎么制作教程/福州seo关键字推广
  • 露兜博客 wordpress/seo站内优化培训
  • 域名为www.com的网站/新网站百度多久收录
  • 网站制作公司中/最近新闻大事
  • 网站建设公司的企业特色有哪些/软文标题写作技巧
  • 西部数码手机网站/网站seo网络优化
  • 教育类网站 前置审批/百度刷搜索词
  • 网站备案 接入商名称/怎么建立个人网站
  • 闵行区做网站/新开店铺怎么做推广
  • 阜宁做网站的公司电话/软文范例大全500字
  • 五力合一营销型网站建设系统/班级优化大师简介
  • 铜川免费做网站/石家庄自动seo
  • 河南郑州网站制作公司/互联网推广引流公司