如何利用 promise 影响代码的执行顺序?

news2025/7/4 20:50:50

如何利用 promise 影响代码的执行顺序?

我们写代码的时候,经常会遇到这样的场景。2个不同组件,它们的生命周期本身都是相互独立,毫无关联的,但是它们调用的接口,存在相互依赖的情况。

我举个例子:

开发小程序时候,里面 App 有一个 onLaunchhook,在小程序初始化时调用,而 Page 里也有一个 onLoadhook,在页面加载时被调用。正常的执行顺序为:

// 应用启动
onLaunch(options)
// do sth....
// 页面加载
onLoad(query) 

但是,我们往往也经常遇到这种 case:

async onLaunch(){store.dispatch('set-token',await getToken())
}
async onLoad(){// getUserInfo 依赖 tokensetUserInfo(await getUserInfo())
} 

现在问题来了,依据上面的执行顺序,getTokengetUserInfo 请求实际上是并发执行的。而我们的预期是,先执行 getToken 并设置好全局 token 值之后,才调用 getUserInfo,这样后端才能依据请求携带的,用户 token 信息,来给我们返回指定的数据,不然那就只有一个 401 了。

那么我们如何让它们之间产生调用的依赖关系呢? 实际上很简单 promiseevent-emitter 都是方法之一。接下来我们来构建一个最小化模型。

最小化模型

我们想要 onLoad一部分的代码的执行在 onLaunch特定代码之后。即把一部分并行跑的代码,变更为串行的顺序,同时也允许原先并行运行的方式。

根据描述,我们天然的就想到了 Microtask,它运行在每个事件循环的执行代码,和运行Task后,Rerender 前。

接下来为了实现期望,我们就需要在 onLaunch 中去产生 Promise,然后到 onLoad 中依据 Promise 状态的变化,执行代码。

那么我们就很容易在一个文件中,构建出一个最小化模型,见下方代码:

let promise

function producer () {console.log('producer start!')promise = new Promise((resolve) => {setTimeout(() => {console.log('promise resolved')resolve(Math.random())}, 2_000)})console.log('producer end!')
}

async function consumer () {console.log('consumer start!')console.log(await promise)console.log('consumer end!')
}

producer()
consumer() 

这段代码中,我在 producer 创建了一个 promise,在 2sresolve 一个随机数,然后再在 consumer 中,去 await 它的状态,变为 fulfilled 后打印 consumer end!。 当然 async/await 只是语法糖,你用 then/catch 也是可以的,不过使用 await 有一个好处就是,它在面对非 Promise 对象的时候,它会自动把值进行包裹转化成 Promise,即 Promise.resolve(value)

接着,让我们把这个模型进行扩充,变为多文件模型。

// ref.js 创建一个引用
export default {promise: undefined
} 
// producer.js
import ref from './ref.js'

export default () => {console.log('producer start!')ref.promise = new Promise((resolve) => {setTimeout(() => {console.log('promise resolved')resolve(Math.random())}, 2_000)})console.log('producer end!')
} 
// consumer.js
import ref from './ref.js'

export default async () => {console.log('consumer start!')console.log(await ref.promise)console.log('consumer end!')
} 
// index.js
import producer from './producer.js'
import consumer from './consumer.js'

producer()
consumer() 

执行结果同理。

移花接木

根据上述的代码,我们就可以对小程序的开发,进行一系列劫持的操作。我们以 uni-app vue2/3 和原生为例。

// vue2
Vue.mixin({created () {if (Array.isArray(this.$options.onLoad) && this.$options.onLoad.length) {this.$options.onLoad = this.$options.onLoad.map(fn => {return async (params:Record<string, any>) => {await ref.promisefn.call(this, params)}})}}
})

// vue3
const app = createSSRApp(App)
app.mixin({created () {if (this.$scope) {const originalOnLoad = this.$scope.onLoadthis.$scope.onLoad = async (params:Record<string, any>) => {await ref.promiseoriginalOnLoad.call(this, params)}}}
})

// native
const nativePage = Page
Page = function (options: Parameters<typeof Page>[0]) {if (options.onLoad && typeof options.onLoad === 'function') {const originalOnLoad = options.onLoadoptions.onLoad = async function (params: Record<string, any>) {await ref.promiseoriginalOnLoad.call(this, params)}}nativePage(options)
} 

思路其实都差不多。

增强

上述的方法,虽然达到了目的,但是实在太简陋了,扩展性也很差。

我们以 ref.js 为例,里面只放了一个 promise 太浪费了,为什么不把它放入全局状态里去呢?这样随时可以取出来进行观察。

为什么不创建多个 Promise queue 呢? 这样还能循环往复地利用不同的队列,来作为代码执行的信道,同时又能够自定义并发度,超时,执行事件间隔等等。p-queue 就是不错的选择。

当然,这些也只是抛砖引玉,这些相信大家各自有各自的看法,反正先做到满足当前的需求,再根据进阶的需求进行适当的改造,做出来的才是最适合自己的。

最后

最近找到一个VUE的文档,它将VUE的各个知识点进行了总结,整理成了《Vue 开发必须知道的36个技巧》。内容比较详实,对各个知识点的讲解也十分到位。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

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

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

相关文章

windows中Mysql数据库的安装和卸载

以安装包“mysql-5.7.35-win32.zip”为例&#xff0c;推荐安装5.7最新版本 一、安装 1、根据自己操作系统版本下载32位或64位的安装包&#xff0c;也可去官网下载&#xff0c;建议下载如下图压缩包 将下载的解压包解压&#xff0c;目录结构如下&#xff1a; 2、新建文件“my.…

IC工程师入门必学,Verilog零基础入门教程

近年来&#xff0c;IC行业发展火热&#xff0c;薪资待遇高&#xff0c;发展前景好&#xff0c;所以成了很多人转行的首选。但IC行业入行门槛高&#xff0c;需要具备相关的知识技能。比如工程师必须至少掌握一种HDL语言。 一般在HDL语言中&#xff0c;Verilog相对来说更加易学、…

负载均衡架构设计技巧

负载均衡算法 轮询&随机 基本原理 轮询&#xff1a;将请求依次发给服务器 随机&#xff1a;将请求随机发给服务器 适用场景 通用&#xff0c;无状态的负载均衡 优缺点 实现简单不会判断服务器状态&#xff0c;除非服务器连接丢失 问题场景 某个服务器当前因为触发…

Java面向对象---尚硅谷Java入门视频学习

1.类和对象 1.1创建过程 对象是将内存地址赋值给了变量&#xff0c;所以变量其实引用了内存中的对象&#xff0c;所以称之为引用变量&#xff0c;而变量的类型&#xff08;即类&#xff09;称之为引用数据类型。 堆&#xff08;Heap&#xff09;&#xff0c;此内存区域的唯…

关于pytorch的数据处理-数据加载Dataset

目录 1. 数据加载 2. Dataset __init__ __getitem__ __len__ 测试一下 完整代码 3. Dataset - ImageFolder 1. 数据加载 最近在使用 Unet 做图像分割&#xff0c;设计到 处理数据有关的工作&#xff0c;查了点资料&#xff0c;做一些简单的总结 在pytorch 中&#x…

Thinkphp安装报错解决办法

跟着官方文档的步骤安装thinkphp报错该如何解决&#xff1a; 前言 ThinkPHP无需安装过程&#xff0c;但是需要把ThinkPHP框架放入WEB运行环境&#xff08;前提是你的WEB运行环境没有问题&#xff09;。 一、Thinkphp安装以及报错解决方式 Thinkphp官网&#xff1a;安装ThinkP…

Mysql为何不推荐写多表SQL

前言 在大部分情况下&#xff0c;单表并不是比多表快单表优势在于理解成本与可控性有时候你觉得单表SQL不好写的时候&#xff0c;你改更新的是表结构 现状 在我们学习MySql的路程之中&#xff0c;估计不少人告诫我们不要写长语句。 至于为什么&#xff0c;确实很少人提起。 …

2.6 用一套万能文案公式来拆解4个小红书爆文案例【玩赚小红书】

公式细分人群他们的痛点数字干货分享情感共鸣 我们一个一个来看。 ​ ​ 一、《9平次卧小房间&#xff0c;再见了传统榻榻米&#xff08;附户型图&#xff09;》 家装类&#xff1a;避坑/攻略/小价钱装出大效果/装修效果拔群 标题直接点出了目标人群的需求&#xff1a;如何…

XSS进阶之CSP绕过

目录预备知识实验目的实验环境实验步骤一实验步骤二实验步骤三预备知识 1.了解Javascript、PHP和CSP的一些特性&#xff0c;比如“strict-dynamic”。 2.CSP&#xff1a;实质就是白名单制度&#xff0c;它规定哪些外部资源可以加载和执行。它的实现和执行全部由浏览器完成。资…

python实战指西<1>pygame安装,以及vscode

目录 1&#xff0c;安装pygame 1.1&#xff0c;&#xff08;如果前一个没反应的化&#xff09; 1.2如果飘红字 1&#xff0c;检查是否开了网络代理&#xff08;不要开&#xff09; 2&#xff0c;检查是否有pip模块更新需要 2.这里顺便记录一下vscode 蛇蛇的环境搭载 2.1首…

Postgresql实验系列(4)SIMD提升线性搜索性能24.5%(附带PG SIMD完整用例)

概要 接上一篇《Postgresql引入SIMD指令集》 PG引入SIMD执行集后具体有多大性能提升&#xff1f;本篇抽取PG的simd库&#xff0c;对比线性搜索场景的性能&#xff1a; 测试场景&#xff08;文章最后提供完整程序&#xff09; 构造一个存有14亿数字的数组 uint32 cnt 14100…

【python3】3.函数、类、模块

2022.11.15 本学习内容总结于莫烦python:3.函数、类、模块 https://mofanpy.com/tutorials/python-basic/interactive-python/function1. Function 函数 我常会重复写一些功能&#xff0c;比如查询文件时间&#xff0c;查询文件名字等等.后续我只需要引用到这个功能&#xff0…

Flink架构重要概念解析-超详理解

文章目录&#x1f48e; 1.1 系统架构1.1.1 整体构成1.1.2 作业管理器&#xff08;JobManager&#xff09;1.1.3 任务管理器&#xff08;TaskManager&#xff09;&#x1f680;1.2 作业提交流程1.2.1 高层级抽象视角1.2.2 独立模式&#xff08;Standalone&#xff09;1.2.3 YARN…

网页数据采集系统-怎样利用爬虫爬网站数据

随着社会不停地发展。人们也是越来越离不开互联网&#xff0c;今天小编就给大家盘点一下免费的网页数据采集系统&#xff0c;只需要点几下鼠标就能轻松爬取数据&#xff0c;不管是导出excel还是自动发布到网站都支持。详细参考图片一、二、三、四&#xff01; 企业人员 通过爬…

【直播预告】相机模型与标定——Real world超级公开课

导言 《Realworld超级公开课》是奥比中光3D视觉开发者社区打造的品牌活动之一&#xff0c;聚焦于3D视觉传感技术。每期课程邀请奥比中光及生态合作伙伴的技术专家&#xff0c;以线上线下相结合的授课形式&#xff0c;面向高校与人工智能企业的开发者&#xff0c;分享3D视觉技术…

线程的“结束”

【一道概率很高的面试题】&#xff1a; 如何优雅的结束一个线程&#xff1f; 上传一个大文件&#xff0c;正在处理费时的计算&#xff0c;如何优雅的结束这个线程呢&#xff1f; 【stop方法】&#xff1a; 【为何不建议使用stop呢&#xff1f;】&#xff1a; 因为很容易产生…

【附源码】计算机毕业设计JAVA成绩分析系统

【附源码】计算机毕业设计JAVA成绩分析系统 目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; JAVA mybati…

ORA-01940 无法删除当前已连接的用户之解决方案(脚本)

第一部分&#xff1a;配置数据库连接 1. 安装ODBC yum -y install unixODBC unixODBC-devel 2. 安装Oracle-instantclient #以下所有操作使用root账号执行 #创建目录 mkdir -p /opt/oracle cd /opt/oracle #下载odbc安装包 wget https://download.oracle.com/otn_software…

计算机毕业设计ssm+vue基本微信小程序的好物推荐分享系统

项目介绍 我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,好物分享系统小程序被用户普遍使用,为方便用户能够可以随时进行好物分享系统小程序的数据信息管理,特开发了基于好物分…

做食品能入驻Lazada吗?带你解锁东南亚当地热销及需求食品系列

中国的电商领域已经趋于饱和状态&#xff0c;中国食品电商领域已经呈现出存量的趋势了&#xff0c;例如&#xff1a;良品铺子、三只松鼠、百草味、口水娃、盼盼等国内知名品牌已经占比了国内大部分的市场份额&#xff0c;跟着巨头抢市场 无疑是很难的&#xff0c;那么中国这么多…