队列:一个先进先出的数据结构
队列
JS中没有队列但是可以用Array来实现队列的所有功能
let queue = [];
//入队
queue.push(7)
queue.push(8)
//出队
const i1 = queue.shift()//i1 = 7
const i2 = queue.shift()//i2 = 8
队列的应用场景
面对无法同时处理多个问题的场景,通常使用队列,先进先出的特性一个一个解决问题,还可保证有序性。
- 需要先进先出的场景
1、食堂排队打饭
2、JS异步中任务队列
3、计算最近请求次数
计算最近请求次数
输入(请求发起的时刻):inputs = [[],[1],[100],[3001],[3002]]
输出(3000ms内的请求次数):[null,1,2,3,3]
最先请求的时刻,最先离开最近请求的范围中。
思路:有新请求就入队,3000ms前发出的出队。队列长度记为最近请求次数
【leetCode993 最近请求次数】
解释:
var obj = new RecentCounter()
obj(1) = 1
obj(2) = 2
obj(3001) = 3
obj(3002) = 3
//构造函数
var RecentCounter = function() {
this.q = [] //保证方法能访问到队列
};
//类方法,参数t返回ping次数
RecentCounter.prototype.ping = function(t) {
this.q.push(t)
while(this.q[0]<t-3000){
this.q.shift()
}
return this.q.length
};
复杂度分析
时间:O(n)n为while中踢出的个数
空间:O(n)n为队列长度 即 最近请求次数
JS异步中任务队列
JS用队列来处理处理异步任务
因为JS是单线程的,无法同时处理异步中的并发任务。
使用队列先后处理异步任务。
setTimeout(()=>console.log(1),0)//异步任务交给webAPI,执行完后放进任务队列,但在执行主事件之后。
console.log(2)//主事件
打印结果:2、1
Callback Queue
JS事件循环与任务队列:
JS引擎(执行JS)
callback queue 任务队列
WebAPI
- JS代码执行时有一个匿名主事件,会丢到任务队列。
- JS引擎在任务队列拿到事件来执行
- 因为JS是单线程,每次执行一个事件
- 在执行事件的过程中,如果里面有一些异步任务如(DOM操作 ajax setTimeout等)
- 他就交给WebAPI来执行。
- WebAPI执行异步任务结束的时候会把回调函数的JS代码放到任务队列中(异步任务都有回调函数)
- 等任务队列里面前面的事件都执行完了,就通过JS引擎执行。
- 如果回调函数中还有异步任务 就继续循环。