太神奇了,昨晚做了个梦,梦中我悟出一个道理:凡是涉及到异步操作而且需要返回值的函数,一定要封装成 Promise 的形式,假如返回值取决于多个异步操作的结果,那么需要对每个异步操作进行状态的设计,而且需要封装一个 next 函数。,到了晚上才觉到很有意思,所以结合 ajax 设置最短返回时间 和 最大返回时间进行实践:

  1. const PENDING = 'PENDING'
  2. const RESOLVED = 'RESOLVED'
  3. const REJECTED = 'REJECTED'
  4. const FULLFILLED = 'FULLFILLED'
  5. /**
  6. * @desc 异步操作模拟
  7. * @param time 响应时间
  8. * @param isError 是否抛错
  9. */
  10. const mock = (time, isError) => {
  11. return new Promise((resolve, reject) => {
  12. setTimeout(() => {
  13. if (!isError) {
  14. resolve({ user: 'ManbaX' })
  15. } else {
  16. reject('request error')
  17. }
  18. }, time)
  19. })
  20. }
  21. /**
  22. * @desc 生产不同类型请求的工厂函数
  23. * @param time 响应时间
  24. * @param isError 是否抛错
  25. */
  26. var RequestFactory = function (time, isError) {
  27. var request = function () {
  28. return new Promise((resolve, reject) => {
  29. var min = PENDING
  30. var max = PENDING
  31. var state = PENDING
  32. var res = null
  33. var next = function (name) {
  34. const cb = function () {
  35. if (state === RESOLVED) {
  36. resolve(res)
  37. } else {
  38. reject(res)
  39. }
  40. }
  41. if (name === 'res' && min === FULLFILLED) {
  42. cb()
  43. }
  44. if (name === 'min' && (state === RESOLVED || state === REJECTED)) {
  45. cb()
  46. }
  47. if (name === 'max' && state === PENDING) {
  48. reject('timeout')
  49. }
  50. }
  51. setTimeout(() => {
  52. min = FULLFILLED
  53. next('min')
  54. }, 500)
  55. setTimeout(() => {
  56. max = FULLFILLED
  57. next('max')
  58. }, 1000)
  59. mock(time, isError).then(data => {
  60. res = data
  61. state = RESOLVED
  62. next('res')
  63. }).catch(error => {
  64. res = error
  65. state = REJECTED
  66. next('res')
  67. })
  68. })
  69. }
  70. return request
  71. }
  72. // 不超时, 不返回错误
  73. console.time('r1')
  74. RequestFactory(200)().then(res => {
  75. console.log('data: ', res)
  76. }).finally(() => {
  77. console.timeEnd('r1')
  78. })
  79. // 不超时, 返回错误
  80. console.time('r2')
  81. RequestFactory(200, true)().catch(err => {
  82. console.log('error', err)
  83. }).finally(() => {
  84. console.timeEnd('r2')
  85. })
  86. // 超时
  87. console.time('r3')
  88. RequestFactory(2000)().catch(res => {
  89. console.log('error: ', res)
  90. }).finally(() => {
  91. console.timeEnd('r3')
  92. })
  93. console.time('r4')
  94. RequestFactory(2000)().catch(res => {
  95. console.log('error: ', res)
  96. }).finally(() => {
  97. console.timeEnd('r4')
  98. })

上面的运行结果符合预期,本来梦中还有另外一个有意思的东西,但是太模糊了就搞忘记了,下次一定早点记录。

状态机模式 与 ajax 的结合运用的更多相关文章

  1. 状态机模式中的Task与对象池

    Task 抽象带来Task 首先,假设我们有这么一段逻辑:收到一个参数,先校验格式是否正确,再提取相关的参数出来,执行我们的事务,然后构建结果并返回.伪代码如下: /** * 一个engine类 ** ...

  2. 一种开发模式:ajax + ashx + UserControl

    一.ajax+ashx模式的缺点     在web开发过程中,为了提高网站的用户体验,或多或少都会用到ajax技术,甚至有的网站全部采用ajax来实现,大量使用ajax在增强用户体验的同时会带来一些负 ...

  3. Query Object--查询对象模式(下)

    回顾 上一篇对模式进行了介绍,并基于ADO.NET进行了实现,虽然现在ORM框架越来越流行,但是很多中小型的公司仍然是使用ADO.NET来进行数据库操作的,随着项目的需求不断增加,业务不断变化,ADO ...

  4. AJAX(学习笔记一)

    1:什么是AJAX? AJAX是一组英文单词的简写,这组英文单词是 :Asynchronous JavaScript and XML ,翻译成中文的意思是: 异步的JavaScript 和 XML.什 ...

  5. ajax withCredentials在firefox下问题的解释

    1,起因: 跨域的问题一般有两种解决方式比较常用,一是使用jsonp,二是服务端配置cors策略.至于jsonp这里不再赘述,本文主要解释一下cors解决跨域产生的问题 2,cors跨域产生的问题 j ...

  6. 游戏开发设计模式之状态模式 & 有限状态机 & c#委托事件(unity3d 示例实现)

    命令模式:游戏开发设计模式之命令模式(unity3d 示例实现) 对象池模式:游戏开发设计模式之对象池模式(unity3d 示例实现) 原型模式:游戏开发设计模式之原型模式 & unity3d ...

  7. Json,Ajax(0516)

    一.JSON简介: JSON(JavaScript Object Notation)是一种轻量级的数据交换语言,以文字为基础,且易于让人阅读,同时也方便了机器进行解析和生成.JSON简单说就是java ...

  8. $.ajax传递字符串到后台,后台返回json对象

    var mall = { MallID: $("#createId").val().trim(), MallName: $("#createName").val ...

  9. Ajax学习之小结

    ajax: * 同步交互和异步交互:  * 同步交互:客户端发送请求——>等待服务器端处理——>接收响应,这个过程客户端不能做任何其他事情,这种模式叫做同步交互  * 异步交互:客户端发送 ...

随机推荐

  1. Rocket - diplomacy - AddressAdjuster分析

    https://mp.weixin.qq.com/s/UYVSO3XFJmhe5bUD_XbMLg   先介绍如何使用AddressAdjuster,然后分析UI参数的生成及使用.   ​​   1. ...

  2. Chisel3 - Wire & Reg

    https://mp.weixin.qq.com/s/Y26N5P4XOr5e3uyi5XQY-w   不同于Verilog,Chisel中Wire和Reg并不是数据类型,而是数据容器,作为数据的一个 ...

  3. Blender如何设置中文界面

    废话不多说,上图 bingo!!

  4. 移动端border:1px问题解决方案

    了解设备像素和css像素的因该知道,通常我们在写移动端时,是按照设计稿标注的像素除以设备的DPR来写真实的像素, 比如在iPhone6上,我们写的20px字体世界上在视觉效应上有20px; 所以当我们 ...

  5. Java实现 LeetCode 767 重构字符串(ASCII的转换)

    767. 重构字符串 给定一个字符串S,检查是否能重新排布其中的字母,使得两相邻的字符不同. 若可行,输出任意可行的结果.若不可行,返回空字符串. 示例 1: 输入: S = "aab&qu ...

  6. Java实现 泊松分酒

    泊松是法国数学家.物理学家和力学家.他一生致力科学事业,成果颇多.有许多著名的公式定理以他的名字命名,比如概率论中著名的泊松分布. 有一次闲暇时,他提出过一个有趣的问题,后称为:"泊松分酒& ...

  7. 小波学ItDay01--开始学习Servlet

    曾经想过许多的开场白,有热血的,有励志的,最后思前想后还是用这句话开篇吧! 生活不会亏待每一个愿意努力的人-------<摘自某微信群的语录> 今天第一天,结合自己的进度开始学习Servl ...

  8. tcpdump 基于mac地址抓取数据包

    1.刚刚接触tcpdump时,常用tcpdump -i eth1 host 192.168.1.1 这个命令基于ip地址抓取数据包信息. tcpdump -i eth1(接口名称) host 192. ...

  9. SaaS权限设计总结

    2年前转到SaaS部门之后期间断断续续做着权限相关的业务,这篇文章主要回顾下过往的设计以及其原因和利弊. 不过因为是线上业务,会省略掉很多细节以及账号体系和权益相关得部分,只讨论权限相关. 本文也不会 ...

  10. 对Activity启动模式的理解

    对Activity启动模式的理解 应用场景 在已打开多个Activity应用B的前提下,应用A调用应用B后点击返回按钮,需要直接返回到A应用,而不是打开B应用的上一个Activity 一个Task可以 ...