复盘打码功能

最近工作中,需求方提出了一个打印条码的功能,需要将指定样本及其关联实验单的编号全部打印出来。
后端会把我需要的打码入参返回给我,前端需要做的是:引入厂家提供的js文件,调用提供的js方法初始化打印机,从后台获取打码参数,调用打码机打印方法,即可完成打码功能。
备注:涉及到打印的按钮共三种:打印当前样本条码,打印所有样本,打印所有样本并流转至待处理。
与后台沟通后,确定返回的打印参数是一个数组list,以便适应全部打印按钮。循环这个参数list,并逐个打印。

这其中遇到了几个值得记录的问题:

打码机厂家提供的初始化及打印方法放在一个立即执行方法中,无法直接引入调用;
由于初始化打码机、从后台获取参数均为异步方法,且为嵌套方法,那么打码机断开或打印失败时,怎样及时弹出错误提醒;
功能中包含一个全部打印并流转的按钮,如果打印失败,怎样阻止流转方法的调用。
获取打印机时,会把能识别的所有设备都拿到,有可能存在超过两个设备的情况(比如安装了多个打印设备的驱动等等),这时需要提供一个弹框,可以选择待使用的打印机。
2,3的主要难点在于打码机相关的方法均为原生xhr方法,怎样用Promise进行适当改写。

以下针对上面提到的四点一一记录。

1.模块方法改写
直接拿到的是一个min.js文件,核心方法如下:

.

..
var BrowserPrint=function(){...var e = {};e.Device = function(a){...this.send = function(){...}...}return e
}()

采用了立即执行函数来封闭内部私有方法,不会和全局函数互相污染,在原生js或JQuery中用得较多,其实这也是模块化的一种方式,但vue中主要采用import的方式引入文件,因此需要先将该方法导出。改写如下:

let BrowserPrint=function(){...let e = {};e.Device = function(a){...this.send = function(){...}...}return e
}
export default BrowserPrint

2.打印机获取失败提醒
这块出现场景主要是:断开打印机连接,点击打印按钮,无法正常打印时应弹出对应的错误提醒。
这个时候我们要调用的方法包括:获取打印机,再获取打码参数,打印条码。这三个方法均需要按序完成。
获取打印机用的是XMLHttpRequest 原生方法,使用回调函数会导致方法层层嵌套,不利于理解,考虑使用Promise进行改写。由于原方法偏复杂,在方法定义时直接改写难度较大,我选择在调用时封装进Promise中,并对应进行resolve和reject处理,避免回调地狱。

// 初始化打印机
initPrinter(){printerData.printer = browserPrint();return new Promise((resolve,reject)=>{_BrowserPrint.getDefaultDevice("printer", (device)=>{..._BrowserPrint.getLocalDevices((device_list)=>{...if(!Array.isArray(realDeviceList)||realDeviceList.length==0){// 没有获取到打印机typeof reject ==='function'&& reject()}else{typeof resolve ==='function'&& resolve()}}, function(error){typeof reject ==='function'&& reject()},"printer");}, function(error){typeof reject ==='function'&& reject()})})
}
this.initPrinter().then(res=>{}).catch(err=>{utils.msg.error('获取打印机失败')return 'error'
})

注意:定义了reject,调用时必须添加catch方法,否则会报错。

3.多层异步嵌套拿到最内层的结果,再进行相应处理
全部打印并流转是逻辑最复杂的方法,包括:

获取打印机(页面初始化后如果没有断开打印机可以省略这一步);
从后台获取打码参数;
逐一调用打印机进行打印;
打印成功则进行流转,打印失败则弹出错误提醒,并终止逻辑处理。
所有步骤按顺序进行。

其中,步骤1,2可以返回Promise实例,但步骤3仍然是一个xhr原生方法,所以决定在打印方法定义的地方(及下方的send方法)使用Promise进行改写。

// 原始方法
var m = this;
...
this.send = function(d, a, f) {var g = b("POST", l + "write");g && (void 0 !== m && (void 0 === a && (a = m.sendFinishedCallback), void 0 === f && (f = m.sendErrorCallback)), c(g, a, f), g.send(JSON.stringify({device: {name: this.name,uid: this.uid,connection: this.connection,deviceType: this.deviceType,version: this.version,provider: this.provider,manufacturer: this.manufacturer},data: d})))
};
...
function c(a, b, d) {a.onreadystatechange = function() {a.readyState === XMLHttpRequest.DONE && 200 === a.status ? "" === a.responseType ? b(a.responseText) : b(a.response) : a.readyState === XMLHttpRequest.DONE && (d ? d(a.response) : console.log("error occurred with no errorCallback set."))};return a
}
// 修改后的方法
var m = this;
...
this.send = function(d, a, f) {return new Promise((resolve,reject)=>{var g = b("POST", l + "write");g.onreadystatechange = function(){if (g.readyState !== 4) {return;}if (g.status === 200) {// 正确回调resolve("" === g.responseType ? g.responseText : g.response) } else {// 错误回调reject(new Error(g.statusText));}}g && (g.send(JSON.stringify({device: {name: this.name,uid: this.uid,connection: this.connection,deviceType: this.deviceType,version: this.version,provider: this.provider,manufacturer: this.manufacturer},data: d})))})
};

这样步骤3也可以返回Promise实例了。由于步骤1~3是不同打印诉求中都要用到,因此封装成一个公共方法_printTag。接下来遇到的一个问题就是,我怎样知道什么时候打印全部完成?
Promise.all方法仅能处理无依赖关系的多个异步方法。后面发现其实很简单,把嵌套内层的异步方法return出去就可以了。
类似这种结构:

test(){this._test1().then(res=>{return this._test2().then(res=>{console.log('log1')return Promise.resolve('success')})}).then(res=>{console.log('log2')if(res=='success'){console.log('log3')}})},
_test1(){return new Promise((resolve,reject)=>{setTimeout(()=>{resolve('第一步')})})},_test2(){return new Promise((resolve,reject)=>{setTimeout(()=>{resolve('第二步')})})},

调用test方法时,我们希望打印出来的顺序是log1,log2,并且能打印出log3。通过测试发现,对test做以下改动即可:

在这里插入图片描述
改动1保证打印顺序是log1,log2,改动2保证可以拿到返回参数"success",可以执行打印log3。

4.多个打印设备
基本思路是:

获取打印机;
设备超过一台,出现选择设备弹框,停止接下来的打印操作;
弹框中点击“确定”按钮,继续开始打印操作。
其中,在步骤2出现过错误

// 出错代码示例
if(Array.isArray(printerData.deviceList)&&printerData.deviceList.length==1){// 只有一台打印机...
}else{// 存在多个打印机,出现选择设备弹框this.printDialog.visible = true;return 'pause'
}

判断条件有一个漏洞,如果设备超过2个,那么一直会执行else逻辑。
正确的应该是:如果存在超过2个设备或者选择弹框已经出现,则执行打印操作。

// 调整后代码
if((Array.isArray(printerData.deviceList)&&printerData.deviceList.length==1)||this.printDialog.visible){// 只有一台打印机或已出现选择弹框...
}else{// 存在多个打印机,出现选择设备弹框this.printDialog.visible = true;return 'pause'
}

总结:
这项功能的完成用了很多Promise改写,加深了对Promise使用方法的理解,比如必须使用resolve将Promise状态更改为“完成”,链式调用中才能用then;比如Promise调用时必须添加catch方法,否则可能会报错;比如then方法中return的值是下一个链式调用的返回值。这些问题以前都遇到过,但直接使用时经常不在意,出现这样或那样的问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2659224.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

k8s二进制部署--部署高可用

连接上文 notready是因为没有网络,因此无法创建pod k8s的CNI网络插件模式 1.pod内部,容器与容器之间的通信。 在同一个pod中的容器共享资源和网络,使用同一个网络命名空间。 2.同一个node节点之内,不同pod之间的通信。 每个pod都…

通过Python将PDF转为文本,快速提取PDF中的文字

快速高效地从PDF文档中提取信息对于专业人士来说非常重要。处理大量PDF文件时,将PDF转换为可编辑的文本格式可以节省时间和精力。而强大的Python语言正是在这些方面发挥其作用。利用Python中丰富的API,我们可以轻松在Python程序中将PDF转换为文本&#x…

通过Vue自定义指令实现前端埋点

在营销活动中,通过埋点可以获取用户的喜好及交互习惯,从而优化流程,进一步提升用户体验,提高转化率。 在之前的埋点方案实现中,都是在具体的按钮或者图片被点击或者被曝光时主动通过事件去上报埋点。这种方法在项目中…

2022年全国职业院校技能大赛高职组云计算正式赛卷第三场-公有云

2022 年全国职业院校技能大赛高职组云计算赛项试卷 【赛程名称】云计算赛项第三场-公有云 目录 2022 年全国职业院校技能大赛高职组云计算赛项试卷 【赛程名称】云计算赛项第三场-公有云 【任务 1】公有云服务搭建[10 分] 【任务 2】公有云服务运维[10 分] 【任务 3】公有云运维…

[SWPUCTF 2021 新生赛]finalrce

[SWPUCTF 2021 新生赛]finalrce wp 注&#xff1a;本文参考了 NSSCTF Leaderchen 师傅的题解&#xff0c;并修补了其中些许不足。 此外&#xff0c;参考了 命令执行(RCE)面对各种过滤&#xff0c;骚姿势绕过总结 题目代码&#xff1a; <?php highlight_file(__FILE__); …

微软发布安卓版Copilot,可免费使用GPT-4、DALL-E 3

12月27日&#xff0c;微软的Copilot助手&#xff0c;可在谷歌应用商店下载。目前&#xff0c;只有安卓版&#xff0c;ios还无法使用。 Copilot是一款类ChatGPT助手支持中文&#xff0c;可生成文本/代码/图片、分析图片、总结内容等&#xff0c;二者的功能几乎没太大差别。 值…

k8s集群etcd备份与恢复

一、前言 k8s集群使用etcd集群存储数据&#xff0c;如果etcd集群崩溃了&#xff0c;k8s集群的数据就会全部丢失&#xff0c;所以需要日常进行etcd集群数据的备份&#xff0c;预防etcd集群崩溃后可以使用数据备份进行恢复&#xff0c;也可用于重建k8s集群进行数据恢复 二、备份…

sheng的学习笔记-卷积神经网络

源自吴恩达的深度学习课程&#xff0c;仅用于笔记&#xff0c;便于自行复习 导论 1&#xff09;什么是卷积神经网络 卷积神经网络&#xff0c;也就是convolutional neural networks &#xff08;简称CNN&#xff09;&#xff0c;使用卷积算法的神经网络&#xff0c;常用于计…

Pymol入门---安装Windows 多版本下载

Pymol的安装 Pymol需要Anaconda与pymol.....whl文件&#xff0c;Anaconda最好去下载清华提供的镜像&#xff0c;网速会很快 Anaconda 下载地址&#xff1a;点击打开链接 pymol 下载地址&#xff1a;点击打开链接 https://www.lfd.uci.edu/~gohlke/pythonlibs/ 1.1 获取…

【每日一题】【12.24】 - 【12.28】

&#x1f525;博客主页&#xff1a; A_SHOWY&#x1f3a5;系列专栏&#xff1a;力扣刷题总结录 数据结构 云计算 数字图像处理 力扣每日一题_ 本周总结&#xff1a;本周的每日一题比较针对于数学问题的一个应用&#xff0c;如二元一次方程组的求解或者数组求和&#xff0c;同…

SSL证书到期怎么办?续签教程一览

在网络安全中&#xff0c;SSL证书是确保数据传输安全的关键。然而&#xff0c;一旦SSL证书到期&#xff0c;就会导致网站的安全性受到威胁。为了保持网站的正常运行并维护用户信任&#xff0c;及时续签SSL证书是至关重要的。以下是一个简要的SSL证书到期后如何进行续签的教程&a…

浏览器Post请求出现413 Request Entity Too Large (Nginx)

环境 操作系统 window server 2016 前端项目 Vue2 Nginx-1.25.3 一、错误信息 前端是vue项目&#xff0c;打包后部署在Nginx上&#xff0c;前端post请求出现Request Entity Too Large错误信息。 ​这种问题一般是请求实体太大&#xff08;包含参数&#xff0c;文件等&#xf…

vs c++mysql 配置

C/C访问MySQL数据库_c链接数据库陈子青-CSDN博客文章浏览阅读2.7k次&#xff0c;点赞14次&#xff0c;收藏65次。C/C访问MySQL数据库VS2019配置第一步&#xff1a;打开mysql的安装目录&#xff0c;默认安装目录如下&#xff1a;C:\Program Files\MySQL\MySQL Server 8.0&#x…

Flink项目实战篇 基于Flink的城市交通监控平台(下)

系列文章目录 Flink项目实战篇 基于Flink的城市交通监控平台&#xff08;上&#xff09; Flink项目实战篇 基于Flink的城市交通监控平台&#xff08;下&#xff09; 文章目录 系列文章目录4. 智能实时报警4.1 实时套牌分析4.2 实时危险驾驶分析4.3 出警分析4.4 违法车辆轨迹跟…

搜维尔科技:经脉腧穴虚拟针灸VR虚拟教学平台AcuMap软件案例分享

北京中医药大学经脉腧穴VR虚拟教学平台案例 主要产品 HTCvive &#xff0c;AcuMap&#xff1b; 实施内容 一、项目说明 &#xff08;1&#xff09;穴位取穴与体表解剖标志关系&#xff1b;&#xff08;2&#xff09;穴下层次解剖及周围解剖结构展示&#xff1b; &#xf…

Tuxera NTFS for Mac2024免费Mac读写软件下载教程

在日常生活中&#xff0c;我们使用Mac时经常会遇到外部设备不能正常使用的情况&#xff0c;如&#xff1a;U盘、硬盘、软盘等等一系列存储设备&#xff0c;而这些设备的格式大多为NTFS&#xff0c;Mac系统对NTFS格式分区存在一定的兼容性问题&#xff0c;不能正常读写。 那么什…

第十章:构建安全的SSH 服务体系

A_实验案例:构建安全的SSH 服务体系 实验环境 某公司的电子商务站点由专门的网站管理员进行配置和维护&#xff0e;并需要随时从Internet进行远程管理。考虑到易用性和灵活性&#xff0c;在 Web服务器上启用OpenSSH 服务&#xff0c;同时基于安全性考虑&#xff0c;需要对SSH…

Java中XML的解析

1.采用第三方开元工具dom4j完成 使用步骤 1.导包dom4j的jar包 2.add as lib.... 3.创建核心对象, 读取xml得到Document对象 SAXReader sr new SAXReader(); Document doc sr.read(String path); 4.根据Document获取根元素对象 Element root doc.getRootElement(); …

SpringBoot2.7 组件注册、属性绑定

SpringBoot2.7 组件注册 一.组件注册1.Configuration解释案例测试 2.SpringBootConfiguration解释 3. Bean解释 4. Scope解释案例 5.Component解释 6.Import解释作用 7.Controller、Service、Repository、Component解释 二.属性绑定1.ConfigurationProperties作用区别常用情况案…

Cucumber-JVM的示例和运行解析

Cucumber-JVM 是一个支持 Behavior-Driven Development (BDD) 的 Java 框架。在 BDD 中&#xff0c;可以编写可读的描述来表达软件功能的行为&#xff0c;而这些描述也可以作为自动化测试。 Cucumber-JVM 的最小化环境 Cucumber-JVM是BDD的框架&#xff0c; 提供了GWT语法的相…