最近的请求次数
写一个 RecentCounter 类来计算特定时间范围内最近的请求。
请你实现 RecentCounter 类:
RecentCounter() 初始化计数器,请求数为 0 。
int ping(int t) 在时间 t 添加一个新请求,其中 t 表示以毫秒为单位的某个时间,并返回过去 3000 毫秒内发生的所有请求数(包括新请求)。确切地说,返回在 [t-3000, t] 内发生的请求数。
保证 每次对 ping 的调用都使用比之前更大的 t 值。
示例:
输入:
[“RecentCounter”, “ping”, “ping”, “ping”, “ping”]
[[], [1], [100], [3001], [3002]]
输出:
[null, 1, 2, 3, 3]
解释:
RecentCounter recentCounter = new RecentCounter();
recentCounter.ping(1); // requests = [1],范围是 [-2999,1],返回 1
recentCounter.ping(100); // requests = [1, 100],范围是 [-2900,100],返回 2
recentCounter.ping(3001); // requests = [1, 100, 3001],范围是 [1,3001],返回 3
recentCounter.ping(3002); // requests = [1, 100, 3001, 3002],范围是 [2,3002],返回 3
提示:
- 1 <= t <= 109
- 保证每次对 ping 调用所使用的 t 值都 严格递增
- 至多调用 ping 方法 104 次
var RecentCounter = function() {// 定义一个队列this.q = []};/*** @param {number} t* @return {number}*/RecentCounter.prototype.ping = function(t) {// 将请求时间入队列this.q.push(t)// 如果队列中的第一个请求的时间与发起请求的时间在3000以上,就剔除第一个请求while(this.q[0] < t - 3000) {this.q.shift()}// 返回队列的长度return this.q.length};/*** Your RecentCounter object will be instantiated and called as such:* var obj = new RecentCounter()* var param_1 = obj.ping(t)*/
事件循环与任务队列

js在执行函数的时候,同步函数会直接执行,如果遇到异步函数,例如dom操作,ajax,setTimeout,会把他们交给webapi去处理,然后继续执行同步函数,等到异步任务执行结束后,会把回调函数放到任务队列中去执行,等到前面的同步函数执行结束,才会按照队列的顺序来依次执行回调函数。
扩展:promise,setTimeout执行顺序

setTimeout(function() {console.log('setTimeout');})new Promise(function(resolve) {console.log('promise');resolve(true)}).then(function() {console.log('then1');}).then(() => {console.log('then2')})console.log('console');// promise// console// then1// then2// setTimeout
知识点:在当前的微任务没有执行完成时,是不会执行下一个宏任务的。
**
分析:
当执行setTImeout时,会被webapi放到微任务中去,然后开始处理Promise,Promise的构造函数是一个同步函数,会立刻执行,然后遇到.then,会被webapi放到微任务中。然后开始处理下一个同步任务。等到所有同步任务处理结束后,会先去看看当前有没有微任务需要执行,这个时候开始执行微任务,等所有微任务都执行结束,才会执行下一个宏任务setTimeout。
场景解析:
这个就像去银行办业务一样,先要取号进行排号。
一般上边都会印着类似:“您的号码为XX,前边还有XX人。”之类的字样。
因为柜员同时职能处理一个来办理业务的客户,这时每一个来办理业务的人就可以认为是银行柜员的一个宏任务来存在的,当柜员处理完当前客户的问题以后,选择接待下一位,广播报号,也就是下一个宏任务的开始。
所以多个宏任务合在一起就可以认为说有一个任务队列在这,里边是当前银行中所有排号的客户。
任务队列中的都是已经完成的异步操作,而不是说注册一个异步任务就会被放在这个任务队列中,就像在银行中排号,如果叫到你的时候你不在,那么你当前的号牌就作废了,柜员会选择直接跳过进行下一个客户的业务处理,等你回来以后还需要重新取号
而且一个宏任务在执行的过程中,是可以添加一些微任务的,就像在柜台办理业务,你前边的一位老大爷可能在存款,在存款这个业务办理完以后,柜员会问老大爷还有没有其他需要办理的业务,这时老大爷想了一下:“最近P2P爆雷有点儿多,是不是要选择稳一些的理财呢”,然后告诉柜员说,要办一些理财的业务,这时候柜员肯定不能告诉老大爷说:“您再上后边取个号去,重新排队”。
所以本来快轮到你来办理业务,会因为老大爷临时添加的“理财业务”而往后推。
也许老大爷在办完理财以后还想 再办一个信用卡?或者 再买点儿纪念币**?
无论是什么需求,只要是柜员能够帮她办理的,都会在处理你的业务之前来做这些事情,这些都可以认为是微任务。
