[探索] 利用promise做一个请求锁

在最近开发小程序的过程中,遇到一个需求,就是请求的时候header需要带上accessToken, accessToken是通过登陆接口返回的参数,可能会出现过期的情况,则需要重新登陆,所以每次加载小程序都会进行一次本地储存的accessToken校验,但是再小程序的运行机制下,app的onLaunch,加载pages的onLoad会并发执行,在弱网的情况下,并发可能导致accessToken还没校验完,page的请求函数就开始执行了,这样很容易会导致接口异常,本来的解决办法是在每个page页面调接口之前都await一下app.js里面checkAccessToken的方法,但是这样写起来不太友好

解决思路:

在request的基础上封装多一层锁,当accessToekn校验完成之前,其他进来的请求都进行等待,不进行请求,等待校验完成,才开始其他请求

原理分析

  1. 对原有的request请求做一次封装
  2. 利用promise的特性以及js对象存储在内存的特性, 配合async/await,让其他请求等待关键请求完成再开始请求,从而实现请求锁
  3. 首先等待关键请求完成了,再通过返回进入判断是否经过需要

代码分析

首先模拟一次请求

// 模拟一次请求发起
const mockRequest = (name, time = Math.random() * 1000) =>new Promise(reslove => {console.log(`${name}---------------run`);setTimeout(() => {reslove(`${name}---------------done`);}, time);});

定义请求锁

请求锁要管理两种状态,一种是关键请求进行是状态,一种是当关键请求失败了之后,需要等待辅助操作完成的状态

const lock = { wait: null, runing: null };

在request的基础上加一层封装

  1. 参数设置两种,withOutLock用于某些不需要等待的请求直接跳过逻辑,lockOthers用于锁住在关键请求之后进来的请求
  2. 关键请求进来直接执行,
    lock.runing
    直接赋予关键请求的pending状态,当其他请求进来的时候,都直接等待,不进行请求发起,等主要请求进来完成之后,其他才开始执行

// 封装模拟request
const request = async (name,opts = { withOutLock: false, lockOthers: false, hasErr: false }
) => {// 不需要等待的请求直接执行if (opts.withOutLock) {const res = await mockRequest(`${name} - withOutLock`);console.log(res);return;}// 关键请求未执行完成 其他请求进入等待状态if (lock.runing) {console.log(`${name}---------------wating...`);await lock.runing;}// 锁住之后进来的请求if (opts.lockOthers) {lock.runing = mockRequest(name, 4000);let res = await lock.runing;// 清空进行锁lock.runing = null;// 模拟关键请求失败的 需要再次等待其他操作的情况 例如重新登陆等if (opts.hasErr) {lock.wait = mockRequest("关键请求异常处理", 4000);} else {console.log(res);return;}}// 等待模拟关键请求失败的处理if (lock.wait) {console.log(`等待关键请求异常处理中...`);await lock.wait;// 清空等待锁lock.wait = null;console.log(`关键请求异常处理完成`);}const res = await mockRequest(name);console.log(res);return;
};

模拟运行效果


// 并发请求模拟
const mockConcurrent = () => {for (let i = 0; i < 5; i  ) {setTimeout(() => {request(`并发请求${i}`, { withOutLock: i === 0 });}, Math.random() * 100);}
};request("关键请求 - 其他需要等待完成才能进行", {lockOthers: true,hasErr: false
});mockConcurrent();

运行时效果

7bf191c2-3648-4fc7-82ef-0378ab0bea89.png

最后

经过同事的指点,未来还打算探究一下请求池,做请求上下文之类的实现

demo代码: 具体例子代码demo参考

纯技术探索,坑点未知,欢迎指出错误以及不足的地方

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

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

相关文章

【Python】[02]初识Python

Python3的下载安装 根据书上的推荐&#xff0c;我将学习和使用Python3版本&#xff0c;从www.python.org网站&#xff0c;根据对应的操作系统&#xff0c;下载合适的Python版本即可 我的是64位系统&#xff0c;所以我选择的是Windows x86-64 executable installer 下载完成后双…

自己写了一个多行文本溢出文字补全的小库, 说不定你会用得到的

有些时候产品会有这么个需求&#xff0c;希望给文章或者帖子给一个摘要&#xff0c;最多3行&#xff0c;或者其它行数&#xff0c;超出3行会补上...。当然这种很简单&#xff0c;用css可以搞定。但是遇上要求多点的产品&#xff0c;希望补上的是...查看全文&#xff0c;这样的话…

C语言简单程序情话,给你一份程序员的“科技情话”,赶在双十一前脱单吧

说起程序员很多人第一印象都是呆板木讷但你们不知道程序员的浪漫花样给你一份程序员的“科技情话”赶在双十一前&#xff0c;和你暗恋的人表白吧~程序员的情书Void missing_you()For(timemeet_you;;time)Missing_you()自从遇见你&#xff0c;就没有一刻不想你-----------------…

记录好用的软件

【摘要】 平时用的很舒服的软件&#xff0c;做个记录&#xff0c;一直更新。 【Snipaste截图】 一般都会用QQ的截图工具&#xff0c;但是现在很少登QQ&#xff0c;Snipaste截图也很好用&#xff0c;只需要按F1即可截图。 【ScreenToGif】 ScreenToGif可以录制屏幕生成Gif文件。…

阿里90后工程师,如何用AI程序写出双11打call歌?

来自阿里巴巴的90后工程师芦阳&#xff0c;用业余时间开发了一套人工智能作词程序——名字叫做MusicGo&#xff0c;这个程序经过芦阳的“喂养”和设定&#xff0c;可以自己写饶舌歌曲。芦阳加入菜鸟也才仅仅四个月&#xff0c;这是他第一次参加双11备战。作为一名新员工&#x…

编程历史

编程历史&#xff1a; 编程语言的历史早于真正意义的计算机的出现。19世纪就有"可编程的"织布机和钢琴弹奏装置出现&#xff0c;它们都是领域特定语言(DSL)的样例。 从1951年2014年&#xff0c;人类一共发明了256种编程语言&#xff0c;每一种语言的出现都带有某些新…

vue结合ueditor富文本编辑器(换肤分离)

需求 (PC端)做一个可以使用图片上传、视频上传、文件上传功能的富文本组件&#xff0c;简单的文本编辑发布功能,采用socket方式传输&#xff0c; 做法 当时看到这个需求&#xff0c;我觉得是不难的,就去github上找富文本编辑器&#xff0c;因为项目比较急&#xff0c;当时我…

使用MyBatis框架时发现的一些小bug

在大配置MyBatis.xml中&#xff1a; 不能有空节点属性 &#xff0c;否则启动服务器后点击登录没有反应。 异常问题&#xff1a; ause: java.sql.SQLException: Value 0000-00-00 00:00:00 can not be represented as java.sql.Timestamp&#xff1a; 解决办法&#xff1a; HTT…

JSF Tomcat配置示例

JavaServer Faces (JSF)是一个Web应用程序框架&#xff0c;旨在简化基于Web的用户界面的开发集成。 它用于开发和构建服务器端用户界面组件&#xff0c;并在Web应用程序中使用它们。 JSF技术基于Model-View-Controller (MVC)架构&#xff0c;并且通过在页面中使用可重用的UI组件…

JS加密算法简单分析

这次分析百度音乐的评论请求的加密&#xff0c;首先先看包 看到有两个地方1. param&#xff0c;2. sign&#xff0c;基本可以断定sign是用的MD5加密的 那么我们从html页面分析入手&#xff0c;恰巧看到html代码中有写到这么一段 右键点击open in Source panel 熟悉的配方&…

JS 的平凡之路--学习人气眼中的效果(上)

最近看了看人气眼的界面&#xff0c;感觉到学习的地方有很多呀。这里先带大家看看人气值跳动的实现。本篇代码基于Vue2.x.x。 一、概要 首先看一下效果图&#xff1a; 要想实现上面的效果&#xff0c;我们分为这几个部分&#xff1a; 判断元素是否在可视区域内&#xff1b;函数…

[译] Airbnb 在 React Native 上下的赌注(一):概述

原文地址&#xff1a;React Native at Airbnb原文作者&#xff1a;Gabriel Peal译文出自&#xff1a;掘金翻译计划本文永久链接&#xff1a;https://github.com/xitu/gold-miner/blob/master/TODO1/react-native-at-airbnb.md译者&#xff1a;ALVINYEH校对者&#xff1a;ChenDo…

批处理最佳做法

大多数应用程序至少具有一个批处理任务&#xff0c;在后台执行特定的逻辑。 编写批处理作业并不复杂&#xff0c;但是您需要了解一些基本规则&#xff0c;我将列举一些我发现最重要的规则。 从输入类型的角度来看&#xff0c;处理项目可以通过轮询处理项目存储库来实现&#x…

android 360度视频播放器,Android开发VR实战之播放360度全景视频

VR即Virtual Reality虚拟现实。虚拟现实技术是一种可以创建和体验虚拟世界的计算机仿真系统它利用计算机生成一种模拟环境是一种多源信息融合的交互式的三维动态视景和实体行为的系统仿真使用户沉浸到该环境中。那么&#xff0c;如何在Android中去开发VR功能的APP呢&#xff1f…

关于怎么在手机端实现一个拖拽的操作

手机端&#xff0c;肯定是监听touchstart,touchmove,touchend事件 先来看看效果 当拖拽时&#xff0c;拖拽到哪个节点下面&#xff0c;就把哪个节点添加到这个下面 <div>1111</div><div>2222</div><div>3333</div><div>4444</div…

物联网架构成长之路(24)-Docker练习之Compose容器编排

0.前言  一开始学的之后&#xff0c;是想一步到位直接上Kubernetes(K8s)的&#xff0c;后面没想到&#xff0c;好像有点复杂&#xff0c;有些概念不是很懂。因此学习东西还是要循序渐进&#xff0c;慢慢来。先了解单机编排技术Docker Compose&#xff0c;了解一些技术细节及原…

CSS原理解析之模型篇

写在前面&#xff1a;尝试回答几个问题&#xff1a;什么是盒模型&#xff0c;控制盒模型的属性有哪些&#xff1f;Margin、Padding、Border、Width、Height这些属性改变/影响盒模型&#xff0c;但每个属性都会在所有元素上生效么&#xff1f;如果存在区别&#xff0c;那么和元素…

Quartz遇到的问题

本文首次发布于My Blog,作者张琦(Ian),转载请保留原文链接。 有状态和无状态 使用有状态&#xff08;StatefulJob&#xff09;还是无状态的任务&#xff08;Job&#xff09; 在 Quartz 中&#xff0c;基本来说&#xff0c;任务分为有状态和无状态两种。实现 Job 接口的任务缺省…

RIP RETE时间获得PHREAKY

我刚刚完成了我称为PHREAK的新规则算法的一些高级文档&#xff0c;这是混合推理中的一个文字游戏。 它仍然有点粗糙和高水平&#xff0c;但希望仍然很有趣。 它建立在ReteOO之上&#xff0c;非常好阅读。 ReteOO算法 ReteOO是在3、4和5系列发行版中开发的。 它采用RETE算法并应…

Hadoop自学笔记(三)MapReduce简单介绍

1. MapReduce Architecture MapReduce是一套可编程的框架&#xff0c;大部分MapReduce的工作都能够用Pig或者Hive完毕。可是还是要了解MapReduce本身是怎样工作的&#xff0c;由于这才是Hadoop的核心&#xff0c;而且能够为以后优化和自己写做准备。 Job Client, 就是用户 Job …