[VueJsDev] 基础知识 - asyncTool.js异步执行工具
[VueJsDev] 目录列表
https://www.cnblogs.com/pengchenggang/p/17037320.html
asyncTool.js 异步执行工具
::: details 目录
:::
所有的业务逻辑,超过两个后,均要用此工具编写逻辑
Step. 1: getAc 使用方法
- 注册 asyncTool
// src/main.js
import asyncTool from "@/libs/common/asyncTool"
Vue.prototype.$getAc = () => {
return new asyncTool()
}
- 常规使用方法
const ac = this.$getAc()
ac.use(this.businessLogic1)
ac.use(this.businessLogic2)
ac.run()
// methods 里面
businessLogic1 (ctx, next) {
// 业务逻辑1
next()
},
businessLogic2 (ctx, next) {
// 业务逻辑2
next()
},
Meth. 2: use 方法
作用:添加一个函数进入序列
目的:注入上下文ctx 和 next 进入函数体
const ac = this.$getAc()
ac.ctx.abc = 'hello'
ac.use(this.businessLogic1)
ac.run()
// methods 里面
businessLogic1 (ctx, next) {
// ctx 是上下文
// next 是指向下一个函数 使用方法 next()
console.info('ctx.abc', ctx.abc) // hello
}
Meth. 3: run 方法
作用:执行当前方法序列
目的:执行方法序列,可以添加最后一个lastCallBack
const ac = this.$getAc()
ac.use(this.businessLogic1)
ac.use(this.businessLogic2)
ac.use(this.businessLogic3)
// ac.run() // 调用方式1
ac.run(() => { // 调用方式2
// ac对象可以进行分发传递,最后可以进行最后一次尾调用
// 如果用use添加后再run,会产生重复use添加的问题
// doSomething
})
Meth. 4: nextJump 方法
作用:跳过下一个方法
目的:常见于根据条件是否执行下一个方法
businessLogic1 (ctx, next) {
// 业务逻辑1
if (a === 'ok') {
next()
} else {
ctx.nextJump() // 默认跳过下一个方法
}
},
Meth. 5: goto 方法
作用:跳到指定的方法
目的:常见于大跳转的业务逻辑,执行完本逻辑要执行最后几个公共逻辑,跳过中间的check
const ac = this.$getAc()
ac.use(this.businessLogic1)
ac.use(this.businessLogic2)
ac.use(this.businessLogic3)
ac.use(this.businessLogic4)
ac.use(this.businessLogic5)
ac.use(this.businessLogic6, { ref: 'businessLogic6'})
ac.use(this.businessLogic7)
ac.run()
// methods 里面
businessLogic2 (ctx, next) {
// 业务逻辑2
if (a === 'ok') {
next()
} else {
ctx.goto('businessLogic6') // 跳到指定的业务逻辑
}
}
Meth. 6: ifTo 方法
作用:跳过当前方法
目的:常见于条件内部直接判断
// methods 里面
businessLogic1 (ctx, next) {
// 算是个语法糖 目的为占用一行 使得代码简洁
// 加叹号求反的目的是 如果条件不符合 就next,条件符合就执行后面的代码
if (ctx.ifTo(!ctx.modifyIsTrue, next)) return
// 其他业务代码...
}
Meth. 7: 批量动态调用接口
对于一个数组,批量调用接口
getUnLocalNames (ctx, next) {
// 新建和改名字没保存的,不能进行全部保存
let unLocalNames = []
this.tagListByR.forEach(item => {
if (item.type === 'new') {
unLocalNames.push(item.tagName)
}
})
const ac = this.$getAc()
ac.ctx.unLocalNames = unLocalNames
this.tagListByR.forEach(item => {
if (item.type === 'modify') {
ac.use((ctx1, next1) => {
apiRequest('getAppoint', { id: item.filePath }).then(data => {
if (item.tagName !== data.xingMing) {
ctx1.unLocalNames.push(item.tagName)
}
next1()
}, err => {
alert(err)
})
})
}
})
ac.run(() => {
ctx.unLocalNames = unLocalNames
next()
})
},
Code. 8: asyncTool.js 源码
// @/libs/common/asyncTool.js
// 创建时间 2020.03.11
// 更新于 2022.08.29
class asyncTool {
// eslint-disable-next-line
constructor() {
this.arr = []
this.ctx = {
goto: this.goto,
_root: this,
ifTo: this.ifTo,
nextJump: this.nextJump,
}
this.cIndex = 0
this.next = null
}
nextJump(number = 1) {
this._root.cIndex = this._root.cIndex + number + 1
const one = this._root.arr[this._root.cIndex]
console.info(
`%cnextJump one 跳过后 ${number}个 的执行函数是: ${one.func.name} `,
"color:green",
)
this._root._innerRun(one.func, one.next)
}
ifTo(boolValue, next) {
if (boolValue) {
next()
return true
} else {
return false
}
}
goto(funcName) {
let runIndex = -1
console.info("this.arr", this)
this._root.arr.map((item, index) => {
if (item.ref === funcName) {
runIndex = index
}
})
if (runIndex !== -1) {
this._root.cIndex = runIndex
this._root._innerRun(
this._root.arr[runIndex].func,
this._root.arr[runIndex].next,
)
} else {
console.error("未找到goto方法名为" + funcName + "的函数")
}
}
use(func, outParams) {
const initParams = {
ref: "",
}
const params = { ...initParams, ...outParams }
const into = {
...params,
func,
next: () => {},
}
this.arr.push(into)
if (this.arr.length > 1) {
const index = this.arr.length - 2
const nextFunc = () => {
// console.info('func.length', func.length)
this.cIndex = index + 1
this._innerRun(func, this.arr[index + 1].next)
}
this.arr[index].next = nextFunc
}
return this
}
getFuncName(fun) {
// console.info('fun', fun.toString())
var ret = fun.toString()
ret = ret.substr("function ".length)
ret = ret.substr(0, ret.indexOf("("))
return ret
}
_innerRun(func, next) {
// console.info('this', this)
// console.info('func', func)
console.info(
`%cfuncName: ${func.name ? func.name : ""}-${this.getFuncName(
func,
)}-ref:${this.arr[this.cIndex].ref}`,
"color:green",
)
this.next = next
if (func.length === 0) {
func()
}
if (func.length === 1) {
func(next)
}
if (func.length === 2) {
func(this.ctx, next)
}
}
run(lastCallBack) {
// 插入最后回调执行,但是不影响 数组的内容,避免反复执行会重复插入
if (lastCallBack && this.arr.length > 0) {
const lastIndex = this.arr.length - 1
this.arr[lastIndex].next = lastCallBack
}
if (this.arr.length > 0) {
this._innerRun(this.arr[0].func, this.arr[0].next)
// console.info('asyncTool func.length', this.arr[0].func.length)
}
}
}
export default asyncTool
[VueJsDev] 基础知识 - asyncTool.js异步执行工具的更多相关文章
- 浅析JS异步执行机制
前言 JS异步执行机制具有非常重要的地位,尤其体现在回调函数和事件等方面.本文将针对JS异步执行机制进行一个简单的分析. 从一份代码讲起 下面是两个经典的JS定时执行函数,这两个函数的区别相信对JS有 ...
- js 异步执行顺序
参考文章: js 异步执行顺序 1.js的执行顺序,先同步后异步 2.异步中任务队列的执行顺序: 先微任务microtask队列,再宏任务macrotask队列 3.调用Promise 中的res ...
- js异步执行 按需加载 三种方式
js异步执行 按需加载 三种方式 第一种:函数引用 将所需加载方法放在匿名函数中传入 //第一种 函数引用 function loadScript(url,callback){ //创建一个js va ...
- JS异步执行之setTimeout 0的妙用
最近在工作中遇到一些问题,大致是关于js执行问题的.由于没搞清执行顺序,导致出现了一些奇怪的bug. 所以这里整理一些有关异步执行的知识(冰山一角角)... 大家都知道js是单线程的,执行起来是顺序的 ...
- 前端知识总结--js异步事件顺序
js中异步事件中容易混淆的 Promise 和 setTimeout 的执行顺序是怎样的? setTimeout(() => console.log(1), 0); new Promise(fu ...
- js异步执行原理
我们都知道js是一个单线程的语言,所以没办法同时执行俩个进程.所以我们就会用到异步. 异步的形式有哪些那,es5的回调函数.es6的promis等 异步的运行原理我们可以先看下面这段代码 应该很多人都 ...
- Java基础知识强化92:日期工具类的编写和测试案例
1. DateUtil.java,代码如下: package cn.itcast_04; import java.text.ParseException; import java.text.Simpl ...
- Java基础知识强化63:Arrays工具类之方法源码解析
1. Arrays工具类的sort方法: public static void sort(int[] a): 底层是快速排序,知道就可以了,用空看. 2. Arrays工具类的toString方法底层 ...
- Java基础知识强化62:Arrays工具类之概述和使用
1. Arrays工具类: Arrays这个类包含操作数组(比如排序和查找)的各种方法. 2. Arrays的方法: (1)toString方法:把数组转成字符串 public static Stri ...
- Android学习之基础知识三(Android日志工具Log的使用)
Android中的日志工具Log(android.util.Log): 1.打印日志的方法(按级别从低到高排序): Log.v():级别verbose,用于打印最为烦琐,意义最小的日志 Log.d() ...
随机推荐
- 从零开始构建一个电影知识图谱,实现KBQA智能问答[下篇]:Apache jena SPARQL endpoint及推理、KBQA问答Demo超详细教学
从零开始构建一个电影知识图谱,实现KBQA智能问答[下篇]:Apache jena SPARQL endpoint及推理.KBQA问答Demo超详细教学 效果展示: 1.Apache jena SPA ...
- 2.2 CE修改器:未知数值扫描
本关需要扫描未知数只扫描,要在不知道初始值的情况下找到一个在0到500之间的数值.首先,选择"未知的初始值"扫描方式,在数值类型中选择 4 字节,并点击"首次扫描&quo ...
- Win32汇编:汇编版PE结构解析器
PE格式是Windows系统下最常用的可执行文件格式,有些应用必须建立在了解PE文件格式的基础之上,如可执行文件的加密与解密,文件型病毒的查杀等,熟练掌握PE文件结构,有助于软件的分析. 在PE文件中 ...
- SpringBoot2.7集成Swagger3
1.引入pom坐标 <!--swagger--> <dependency> <groupId>io.springfox</groupId> <ar ...
- linux笔记-工作
根据进程id或进程名查看端口号 netstat -antup|grep 2073 netstat -antup|grep processName 查看某个端口号是否被占用 netstat -tln | ...
- 万字手撕AVL树 | 上百行的旋转你真的会了吗?【超用心超详细图文解释 | 一篇学会AVL】
说在前面 今天这篇博客,是博主今年以来最最用心的一篇博客.我们也很久没有更新数据结构系列了,几个月前博主用心深入的学习了这颗二叉平衡搜索树,博主被它的查找效率深深吸引. AVL树出自1962年中的一篇 ...
- (python)每日代码||2024.1.27||类方法与实例方法
class test(): aaa = 111 bbb = 222 ccc = 333 @classmethod def cm(cls): cls.aaa="***" def im ...
- 零基础入门Vue之画龙点睛——再探监测数据
追忆 上一节:零基础入门Vue之影分身之术--列表渲染&渲染原理浅析 虽然我深知,大佬告诉我"先学应用层在了解底层,以应用层去理解底层",但Vue的数据如何检测的我不得不去 ...
- 【Flink入门修炼】1-3 Flink WordCount 入门实现
本篇文章将带大家运行 Flink 最简单的程序 WordCount.先实践后理论,对其基本输入输出.编程代码有初步了解,后续篇章再对 Flink 的各种概念和架构进行介绍. 下面将从创建项目开始,介绍 ...
- 《AI驱动下的开发者新生态》-2024长沙.NET技术社区活动-诚邀大家报名
回顾 2019年初,在.NET中文社区及包括苏州.广州.深圳等地区社区等大力推动.在众多企业的大力支持下,长沙地区的开发者们发起成立了长沙.NET技术社区,并组织了<2019年长沙开发者技术大会 ...