状态机模式 与 ajax 的结合运用
太神奇了,昨晚做了个梦,梦中我悟出一个道理:凡是涉及到异步操作而且需要返回值的函数,一定要封装成 Promise 的形式,假如返回值取决于多个异步操作的结果,那么需要对每个异步操作进行状态的设计,而且需要封装一个 next 函数。,到了晚上才觉到很有意思,所以结合 ajax 设置最短返回时间 和 最大返回时间进行实践:
const PENDING = 'PENDING'
const RESOLVED = 'RESOLVED'
const REJECTED = 'REJECTED'
const FULLFILLED = 'FULLFILLED'
/**
* @desc 异步操作模拟
* @param time 响应时间
* @param isError 是否抛错
*/
const mock = (time, isError) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (!isError) {
resolve({ user: 'ManbaX' })
} else {
reject('request error')
}
}, time)
})
}
/**
* @desc 生产不同类型请求的工厂函数
* @param time 响应时间
* @param isError 是否抛错
*/
var RequestFactory = function (time, isError) {
var request = function () {
return new Promise((resolve, reject) => {
var min = PENDING
var max = PENDING
var state = PENDING
var res = null
var next = function (name) {
const cb = function () {
if (state === RESOLVED) {
resolve(res)
} else {
reject(res)
}
}
if (name === 'res' && min === FULLFILLED) {
cb()
}
if (name === 'min' && (state === RESOLVED || state === REJECTED)) {
cb()
}
if (name === 'max' && state === PENDING) {
reject('timeout')
}
}
setTimeout(() => {
min = FULLFILLED
next('min')
}, 500)
setTimeout(() => {
max = FULLFILLED
next('max')
}, 1000)
mock(time, isError).then(data => {
res = data
state = RESOLVED
next('res')
}).catch(error => {
res = error
state = REJECTED
next('res')
})
})
}
return request
}
// 不超时, 不返回错误
console.time('r1')
RequestFactory(200)().then(res => {
console.log('data: ', res)
}).finally(() => {
console.timeEnd('r1')
})
// 不超时, 返回错误
console.time('r2')
RequestFactory(200, true)().catch(err => {
console.log('error', err)
}).finally(() => {
console.timeEnd('r2')
})
// 超时
console.time('r3')
RequestFactory(2000)().catch(res => {
console.log('error: ', res)
}).finally(() => {
console.timeEnd('r3')
})
console.time('r4')
RequestFactory(2000)().catch(res => {
console.log('error: ', res)
}).finally(() => {
console.timeEnd('r4')
})

上面的运行结果符合预期,本来梦中还有另外一个有意思的东西,但是太模糊了就搞忘记了,下次一定早点记录。
状态机模式 与 ajax 的结合运用的更多相关文章
- 状态机模式中的Task与对象池
Task 抽象带来Task 首先,假设我们有这么一段逻辑:收到一个参数,先校验格式是否正确,再提取相关的参数出来,执行我们的事务,然后构建结果并返回.伪代码如下: /** * 一个engine类 ** ...
- 一种开发模式:ajax + ashx + UserControl
一.ajax+ashx模式的缺点 在web开发过程中,为了提高网站的用户体验,或多或少都会用到ajax技术,甚至有的网站全部采用ajax来实现,大量使用ajax在增强用户体验的同时会带来一些负 ...
- Query Object--查询对象模式(下)
回顾 上一篇对模式进行了介绍,并基于ADO.NET进行了实现,虽然现在ORM框架越来越流行,但是很多中小型的公司仍然是使用ADO.NET来进行数据库操作的,随着项目的需求不断增加,业务不断变化,ADO ...
- AJAX(学习笔记一)
1:什么是AJAX? AJAX是一组英文单词的简写,这组英文单词是 :Asynchronous JavaScript and XML ,翻译成中文的意思是: 异步的JavaScript 和 XML.什 ...
- ajax withCredentials在firefox下问题的解释
1,起因: 跨域的问题一般有两种解决方式比较常用,一是使用jsonp,二是服务端配置cors策略.至于jsonp这里不再赘述,本文主要解释一下cors解决跨域产生的问题 2,cors跨域产生的问题 j ...
- 游戏开发设计模式之状态模式 & 有限状态机 & c#委托事件(unity3d 示例实现)
命令模式:游戏开发设计模式之命令模式(unity3d 示例实现) 对象池模式:游戏开发设计模式之对象池模式(unity3d 示例实现) 原型模式:游戏开发设计模式之原型模式 & unity3d ...
- Json,Ajax(0516)
一.JSON简介: JSON(JavaScript Object Notation)是一种轻量级的数据交换语言,以文字为基础,且易于让人阅读,同时也方便了机器进行解析和生成.JSON简单说就是java ...
- $.ajax传递字符串到后台,后台返回json对象
var mall = { MallID: $("#createId").val().trim(), MallName: $("#createName").val ...
- Ajax学习之小结
ajax: * 同步交互和异步交互: * 同步交互:客户端发送请求——>等待服务器端处理——>接收响应,这个过程客户端不能做任何其他事情,这种模式叫做同步交互 * 异步交互:客户端发送 ...
随机推荐
- PowerPC-Link Command File解析
https://mp.weixin.qq.com/s/CATWma2mv5IPYGtKZLuGDA 以Code Warrior 11生成的flash版本(FLASH.lcf)为例 一. 参考资 ...
- Java实现 蓝桥杯VIP 基础练习 回形取数
问题描述 回形取数就是沿矩阵的边取数,若当前方向上无数可取或已经取过,则左转90度.一开始位于矩阵左上角,方向向下. 输入格式 输入第一行是两个不超过200的正整数m, n,表示矩阵的行和列.接下来m ...
- java实现第七届蓝桥杯阶乘位数
阶乘位数 阶乘位数 9的阶乘等于:362880 它的二进制表示为:1011000100110000000 这个数字共有19位. 请你计算,9999 的阶乘的二进制表示一共有多少位? 注意:需要提交的是 ...
- 总结梳理:webpack中如何使用vue
1. 安装vue的包 cnpm i vue -S 2. 由于在webpack中,推荐使用 .vue这个组件模板文件定义的组件,所以,需要安装, 能解析这个文件的loader: cnpm i vu ...
- Scrapy 小技巧(一):使用 scrapy 自带的函数(follow & follow_all)优雅的生成下一个请求
前言 如何优雅的获取同一个网站上下一次爬取的链接并放到生成一个 Scrapy Response 呢? 样例 from urllib import parse import scrapy class S ...
- Node第三方模块
node第三方模块集合 1.nrm 切换npm下载的镜像地址 nrm ls 查看可用镜像 nrm use +镜像名 2.nodemon 在控制台nodenom替代node命令执行nodejs文件, ...
- [原创][开源] SunnyUI.Net 系列文章目录
SunnyUI.Net, 基于 C# .Net WinForm 开源控件库.工具类库.扩展类库.多页面开发框架 Blog: https://www.cnblogs.com/yhuse Gitee: h ...
- 滴滴HBase大版本滚动升级之旅
桔妹导读:滴滴HBase团队日前完成了0.98版本 -> 1.4.8版本滚动升级,用户无感知.新版本为我们带来了丰富的新特性,在性能.稳定性与易用性方便也均有很大提升.我们将整个升级过程中面临的 ...
- markdown分页导出pdf
在需要分页之处,插入代码: <div STYLE="page-break-after: always;"></div>
- vuex登录验证及保持登录状态
不知道vuex的可以先看一下 vuex官方文档,这里就不赘述了. 实现思路:假设我们现在想要访问自己在博客园里写的博客,这时候服务器需要知道当前用户是谁,才能确定我们是否有访问权限并正确地返回我们需要 ...