JS 异步队列的实现

这可能是个比较深的话题。何谓异步?

  笼统地说,异步在javascript就是延时执行。严格来说,javascript中的异步编程能力都是由BOM与DOM提供的,如setTimeout,XMLHttpRequest,还有DOM的事件机制,还有HTML5新增加的webwork, postMessage,等等很多。这些东西都有一个共同的特点,就是拥有一个回调函数,实现控制反转。由于控制反转是更深奥的问题,这里不想展开。不过有点可以确认的,回调函数的存在打断了原来的执行流程,让它们自行在适当的时机出现并执行,这是个非常便捷的模式。对比主动式的轮询,你就知它多么节能。在同步编程,代码基本上自上向下执行,在异步编程,一些代码就要写到回调函数中,如果代码之间存在依赖,回调函数套回调函数的情况也不少见,这种套嵌结构对以后的维护来说简直是地狱。还有一种我们不得不面对的情况,try...catch无法捕捉几毫秒之后发生的异常。另外,除了setTimeout外,异步编程基本上由事件机制承担的,它们的回调函数什么时候发生基本上都是未知数,可能由于后台发生系统级错误,无法再发出响应,或者,系统忙碌,一时半刻响应不过来,这两种情况我们也必需提供一个策略,中断这操作,也就是所谓的abort,这些都是异步编程的所要处理的课题。


   
$.post( " /foo.json " , function (dataOfFoo) { // 多层套嵌结构的Ajax回调
$.post( " /bar.json " , function (dataOfBar) {
$.post(
" /baz.json " , function (dataOfBaz) {
alert([dataOfFoo, dataOfBar, dataOfBaz]);
});
});
});

function throwError(){
throw new Error( ' ERROR ' );
}

try {
setTimeout(throwError,
3000 );
}
catch (e){
alert(e);
// 这里的异常无法捕获
}

  由于在javascript编程,随时都碰到这样的需求,因此实现相关轻捷的API是重中之重。正如上面所说,它只少要有以下功能,能储存一组回调函数(domReary,多投事件,特效),在特定时刻中执行所有回调函数,如果发生错误能触发相应的处理函数(负向回调),能中止整个操作,从中断处再起操作,如果要求更多,我们还想能从串行转向并行,由并行转入串行。可能有许多概念大家听不懂,是不是?但想弄个好的特效,这些都是必需的。如果玩过后端JS的人,一定听说过node.js,现在基本成为它的代名词了。路由派发,IO操作,都是异步的,事件驱动的,为了实现优雅的异步编程,大牛们忙得焦头烂额,一个个方案被提出来,如do.js. step.js, async.js, flow.js……,不是太鸡肋,就是无法应用于前端。因此我们需要一个适合于前端的方案。

  有件事我们必需明白,你想到的,人家都早已研究过了,并且已给出解决方案。十大javascript框架之一,Mochikit,就从Python的Twisted库搞来Deferred,后来又给dojo学去,现在你们又看到,相同的东西又出现在jQuery1.5上了。不过,Mochikit的Deferred还有一个不为人知的分支,由日本大牛cho45搞出来(他同时也搞什么BigInt,跨浏览器Testing,名气紧随amachang、uupaa、edvakf、nanto之后),叫JSDeferred。先说dojo那派系的(包括jQuery)的Deferred,一直处于无敌状态,与Common.js搞出一套规范,什么promises,then,when都是那时制定,jQuer基本全盘接受。另一分支,cho45的JSDeferred,构思非常奇特,没有使用数组来装载回调函数,而是通过setTimeout,image.onload, postMessage等异步机制巧妙地把维护列队地工作道回浏览器自身,虽然有致命缺陷,但其易用性也被日本JS界所首肯,我的Deferred对象就从它的基本上发展过来的。Deferred这东西,我通常称之为异步列队,因为它们的确是需要两组由回调函接构成的队列,非常之形象。

  在我们搬出异步列队之前,让我们看看普通的列队是怎么实现延迟的。


   
var Queue = function (){
this .list = []
}
Queue.prototype
= {
constructor:Queue,
queue:
function (fn) {
this .list.push(fn)
return this ;
},
dequeue:
function (){
var fn = this .list.shift() || function (){};
fn.call(
this )
}
}

  这样调用它:


   
var q = new Queue;
q.queue(
function (){
log(
1 )
}).queue(
function (){
log(
2 )
}).queue(
function (){
log(
3 )
});
while (q.list.length){
q.dequeune();
}

  但这是同步,想异步,我们需要用setTimeout:


   
var el = document.getElementById( " test " );
var q = new Queue();
q.queue(
function (){
var self = this ;
el.innerHTML
= 1
setTimeout(
function (){
self.dequeue()
},
1000 );
}).queue(
function (){
var self = this ;
el.innerHTML
= 2
setTimeout(
function (){
self.dequeue()
},
1000 );
}).queue(
function (){
var self = this ;
el.innerHTML
= 3
setTimeout(
function (){
self.dequeue()
},
1000 );
}).dequeue()

  如大家所见,这样写绝对不友好。我们需要把setTimeout整到Queue类中去,另对queue做一些修改,不要只弹出一个函数进行执行,通常情况下会对列队中的所有回调进行操作的,如domReay,多投事件。


   
var Queue = function (){
this .list = []
}
Queue.prototype
= {
constructor:Queue,
queue:
function (fn) {
this .list.push(fn)
return this ;
},
wait:
function (ms){
this .list.push(ms)
return this ;
},
dequeue:
function (){
var self = this , list = self.list;
var el = list.shift() || function (){};
if ( typeof el == " number " ){
setTimeout(
function (){
self.dequeue();
},el);
}
else if ( typeof el == " function " ) {
el.call(
this )
if (list.length)
self.dequeue();
}
}
}

  Great,如果我们能自由控制每个回调的间隔,这对于做动画效果说,就变得非常简单了。但这Queue类相对我们最初定下的目标来说,还是差得远。Ajax,多投事件,domReay将统统划归于它的麾下,因此它需要用一些适用性更强的API。用过dojo的人也知,它的Deferred就像DNA的染色体一样,是双线的,可以捕捉不在同一时间线上的异常,而且这些列队不能像卫生筷那样用完一次就废了,这样就无法支撑多投事件的实现了。想要实现这些功能,就需要一个很复杂的东西,我将在第二部分隆重介绍我的异步列队,看它是如何优雅地解决这些问题。

转载于:https://my.oschina.net/u/249393/blog/268061

JS中的算法与数据结构之队列(Queue)实例详解 主要介绍了JS中的算法与数据结构之队列(Queue),结合实例形式详细分析了javascript中队列的概念、原理、定义及常见操作技巧,需要的朋友可以参考下 立即下载

相关推荐

四足机器人通用运动控制策略:强化学习与PD参数优化

运动控制是机器人实现稳定行走和复杂动作的核心技术,其关键在于精确调节关节的刚度和阻尼特性。PD控制器作为基础控制单元,通过比例(P)和微分(D)增益参数直接影响系统响应速度与稳定性。在四足机器人领域,强化学习(RL)通过模拟环境自主学习,能够有效解决传统控制方法难以适应不同形态机器人的痛点。该技术通过非对称Actor-Critic架构,结合状态估计网络和自适应参数采样策略,实现了跨平台的通用运动控制。典型应用包括工业检测、灾害救援等需要高适应性移动能力的场景,其中PD增益优化和形态参数自适应采样成为提升硬件

weixin_30307921的博客 299

javascript 异步编程

这可能是个比较深的话题。何谓异步? 笼统地说,异步在javascript就是延时执行。严格来说,javascript中的异步编程能力都是由BOM与DOM提供的,如setTimeout,XMLHttpRequest,还有DOM的事件机制,还有HTML5新增加的webwork, postMessage,等等很多。这些东西都有一个共同的特点,就是拥有一个回调函数,实现控制反转。由于控制反转是更深奥的问...

weixin_33724059的博客 277

Win10/Win11共享打印机0x00000709终极修复指南:从注册表到LPD协议的全面解决方案

本文提供了Win10/Win11共享打印机0x00000709错误的终极修复指南,涵盖从注册表修改到LPD协议的全面解决方案。通过详细分析错误根源、基础修复四步法、高阶LPD协议方案及企业级深度修复策略,帮助用户彻底解决打印机共享问题,提升局域网打印效率。

weixin_33724046的博客 310

js异步队列函数

先上源代码: 8.31 虽然很努力的维护,但是还是出现了严重的BUG,这版修复。 7.25 修复num参数为1不能执行的错误。 7.24 发布。 /** * 这是一个异步队列处理程序 * @param list * 这个必须是数组 * @param fn * 每元素处理的方法,fn默认会传入当前操作的元素以及元素的索引下标 *

hahadekuai的专栏 1942

告别ROS1思维:在ROS2 Humble上,用Python搞定MoveIt2机械臂控制的完整流程

本文详细介绍了在ROS2 Humble环境下使用Python控制MoveIt2机械臂的完整流程。从环境配置、架构变革到实战操作,涵盖URDF适配、Action接口编程及性能优化技巧,帮助开发者高效迁移ROS1项目至ROS2平台,实现工业级机械臂控制。

weixin_30352645的博客 449

ABAP RANGES及比较符号

RANGES *选项介绍: *1.SIGN 值为 I 和 E 。 I是包含, E是排除, 一般使用I。 2.OPTION 如果HIGH 为空 ,为单值选择 。有 EQ、NE、GT、LE、LT等逻辑操作 对于的 CP包含 NP是排除 如果HIGH 不为空 为区间选择 有BT,NB可选 *3.LOW 低值 *4.HIGH 高值 lt:less than 小于 le:less than or equal to 小于等于 eq:equal to 等于 ne:

Pegasus666的博客 5389

javascript队列的实际应用场景案例

概念 队列是JavaScript中的一种数据结构,遵循先进先出(FIFO / First In First Out)的规则。队列可以理解为食堂排队取餐的场景,先排队的取到餐后先去吃饭。 实现 class Queue { constructor(items) { this.items = items || [] } // 入列 enqueue = ele => { this.items.push(ele) } // 出列

qq_16139383的博客 866

OpenClaw 在 Docker 容器中的部署实战——零配置启动

本文介绍了OpenClaw在Docker容器中的快速部署方法,对比了本地部署与容器化部署的优势。通过官方镜像和Docker Compose两种方式,5分钟即可完成部署,并详细讲解了配置管理方案(挂载配置文件和环境变量)。文章还提供了飞书集成配置方法,以及生产环境下的日志管理、资源限制、健康检查等优化建议。最后包含常见问题排查指南,帮助开发者快速实现OpenClaw的容器化部署。

刘一说的IT专栏 904

一个小例子很好解释了JS的事件队列

for (var i=0;i<5;i++){ (function (i) { console.log(i); i = i*10; setTimeout(function () { console.log(i) },500); })(i);

q1325545052的博客 737

【AI智能体】飞书 AI 智能客服机器人搭建与使用实战操作详解

飞书 AI 智能客服机器人搭建与使用实战操作详解

congge 6050

Ardupilot无人船(车)mavros自主控制

rover 4.4。

超维空间科技的博客 3229

js实现队列

队列是一种特殊的线性表,具有先进先出的特性。 在 JavaScript 中,可以使用数组来实现队列。下面是一个简单的队列类的例子: class Queue { constructor() { this.items = []; } enqueue(element) { this.items.push(element); } dequeue() { if...

weixin_35752233的博客 433

大数据ZooKeeper(一):ZooKeeper基本知识

Zookeeper是一个分布式协调服务的开源框架。主要用来解决分布式集群中应用系统的一致性问题。ZooKeeper本质上是一个。

Lansonli(蓝深李)的博客 3149

JavaScript 异步队列实现及拓展

简单介绍回顾一下,因为有同学不经常用,肯定会有遗忘。// 一个简单的栗子,介绍它的用法// 12return y;// 2// {value: 12, done: true}复制代码首先生成器其实就是一个通过函数体内部定义迭代算法,然后返回一个 iterator 对象。关于iterator,可以看我另一篇文章。gen 执行返回一个对象 g,而不是返回结果。

weixin_64051447的博客 778

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

JavaScript 异步队列及Co实现

引入 队列对于任何语言来说都是重要的,io 的串行,请求的并行等等。在 JavaScript 中,又由于单线程的原因,异步编程又是非常重要的。昨天由一道面试题的启发,我去实现 JS 中的异步队列的时候,借鉴了 express 中间件思想,并发散到 co 实现 与 generator,以及 asyncToGenerator。 本次用例代码都...

weixin_33762130的博客 211

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

js promise 实现异步队列

使用 import {Queue} from "@/promiseQueue" const queue = new Queue() queue.enqueue((resolve,reject) => { try { // do something resolve(result) } catch (err) { reject(err) } }).then(result=>{ console.log('success') }).catch

路过君的博客 906

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

2023年最新JavaScript 基础面试题

使用原生JavaScript或WebSocket库,编写一个WebSocket客户端,连接到指定的服务器,并处理接收到的消息。编写一个异步队列,支持添加任务和批量执行任务的功能。每个任务都是一个异步函数,队列需要保证任务按照添加的顺序执行。类似于Express.js的路由功能,但使用原生JavaScript和Node.js的HTTP模块来实现。定义一个树节点类,并在该类中实现一个方法来搜索树中是否存在某个值。

卡拉米 608

面试题-实现异步队列

实现异步队列 实现异步队列函数,使其能够按照参数顺序依次输出 function fun1(cb) { setTimeout(function() { console.log('fun1'); cb(); }, 3000) } function fun2(cb) { setTimeout(function() { console.log('fun2'); cb(); }, 1000) } function fun3(cb) { setTimeout(func

xiaojinglyd的博客 273

单线程异步!(自己学习整理)

这是我自己学习整理,不希望误导别人! 如果你想学习可以到以下网址查看:   Javascript是单线程的深入分析: http://blog.youkuaiyun.com/talking12391239/article/details/21168489 阮一峰:http://www.ruanyifeng.com/blog/2014/10/event-loop.html 单线

百九 2491

JavaScript 实现企业微信消息自动发送的技术实践

在日常的研发与团队协作中,将关键的业务日志、部署结果、或是线上告警实时推送到企业微信中,是提升团队响应效率的重要手段。今天和大家分享一个通过轻量级 API 接口实现企业微信消息自动发送的技术实践。本方案不依赖复杂的官方多重验证,非常适合需要快速验证业务逻辑的开发团队或搭建内部效率工具。

2501_94198109的博客 226

Vue.js 深度解析:nextTick 原理与应用

本文将带你深入理解 Vue.js 中的 nextTick 机制,剖析其工作原理,并学会如何正确使用 nextTick 来优化我们的代码。通过 MD 语法和多级标题结构,为你呈现一部适合 优快云 发布的技术博客。🎉nextTick 是 Vue.js 提供的一个方法,用于在下一个 DOM 更新周期后执行一些操作。在 Vue.js 中,数据的更新是异步进行的,这意味着当我们修改了数据后,DOM 并不会立即更新。nextTick允许我们在数据更新完成后执行一些操作,确保我们的操作基于最新的 DOM 状态。🌈。

你若盛开,清风自来 1516

[js高手之路]javascript腾讯面试题学习封装一个简易的异步队列

这道js的面试题,是这样的,页面上有一个按钮,一个ul,点击按钮的时候,每隔1秒钟向ul的后面追加一个li, 一共追加10个,li的内容从0开始技术( 0, 1, 2, ....9 ),首先我们用闭包封装一个创建li元素的函数. 1 var create = (function(){ 2 var c...

weixin_34081595的博客 110
上一篇: 浏览器控制台(console对象)
下一篇: ORA-03114: not connected to ORACLE
chuban8607
博客等级 码龄11年 2粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值