前端通信:ajax设计方案(十)--- 完善Promise A+规范,增加mock数据功能
同步更新博客: www.cnblogs.com/GerryOfZhon…
同步更新专栏: zhuanlan.zhihu.com/zhongqiang
同步更新github: github.com/GerryIsWarr…
半年不迭代,迭代搞半年,说的就是我,这里有点尴尬了,直接进入主题吧
我记得在这篇博客的时候集成了Promise的,不过那个时候就简简单单的写了一点最基础,在一些特殊的case上,还是有点问题的,所以才有了这个博客。在拜读了w3c和PromiseA+规范之后,从头到尾详细的了解了Promise这个东西,然后自己亲手写了一个和es6文档拥有相同功能的库。
什么是promise?
promise是一个对象,表示单个异步操作的最终结果。
什么时候使用?
任何一门技术都不是一个“万金油”,只有在它最合适的场地出现,才是实现它最大价值的地方,so,Promise一样逃不过这个“真香”定律。
one-and-done操作模型
- 异步I / O操作:从存储API读取或写入的方法可以返回承诺。
- 异步网络操作:通过网络发送或接收数据的方法可以返回承诺。
- 长时间运行的计算:需要一段时间来计算某些东西的方法可以在另一个线程上完成工作,返回结果的承诺。
- 用户界面提示:要求用户回答的方法可以返回承诺。
One-Time "Events”模型
即使在已经履行或被拒绝之后也可以订阅,当某些事情只发生一次,并且作者经常想要在它已经发生之后观察它的状态
更多状态的变化
图像,字体等资源的加载loaded属性,这个属性仅在资源完全加载是才会实现,否则拒绝
不建议使用promise的场景
任何一个可能不止一次发生的事件,都不是one-and-done模型的
大的流数据,分步处理流数据,而无需将流的全部内容缓冲到内存中。
Tips
这里有个w3c组织搞出来的一个指南--Writing Promise-Using Specifications,建议大家拜读一下,虽然没有详细讲解规范,但是对于Promise使用场景和特性做了一次详细的介绍,包括我上面说的使用场景等等。
以上讲的更多偏向应用层的知识点,下面就让我们深入它的根本去了解Promise是如何实现的。
Promise本身是一种社区规范--Promises/A+,由Promise A+组织进行制定,它们提供了一个大纲和指导性的方案,只要能实现其所列规范,都可以视作实现了Promise A+,so,后面的各种变种啊,什么样的功能,都可以根据自己所需去设计,但是基础的方案按照A+ 组织规范实现就可以。
这个大纲比较啰嗦、枯燥、无味,so,我们靠3张我画的图去理解一下Promise
第一张:promise整体流程图
实例化Promise的时候(定义内部状态的初始值等等),在同步状态下,首先会执行初始化代码,比如:new Promise((res,rej)=>{ console.log('这里就是初始化代码') }),然后再执行then方法。这个执行顺序在promise下是错误的,因为在实例代码中会首先改变Promise状态,但是前置的callback还没有在then方法中注入,所以要做推迟实例代码(setTimeout,可以将任务推到执行周期之后,宏任务),让then先跑起来,注入状态变更需要的前置依赖。
在Promise规范中定义了,then方法,必须返回一个Promise,so,Promise2就是then的返回值。然后then的动作就是将所有需要前置依赖的回调函数,Promise状态,状态变化的value全都存储起来。
等待推迟的实例代码(官方叫:异步)执行之后,触发了Promise状态的变化这个动作,然后去改变内部定义的状态,以及状态变化所要执行的操作。
内部状态已经变化完成,但是return的Promise2状态还是pending,所以我们需要将自身的Promise和Promise2的状态进行同步以及是否可then的持续操作。
以上为Promise的整体流程思路,它就是这样跑起来的。不过知道这个流程以后,还是一知半解的,下面我们就对核心方法then进行详细剖析。
第二张:then方法核心解析
then方法需要分3个状态去解析
- pending 状态
a. 首先实例化执行then方法,这个时候初始化的内部状态都是pending,这个时候,我们要做一个订阅和发布的设计,将then传入的resolve和reject的回调进行包装和存储,并订阅触发动作。(这边的包装是因为订阅的时候,不仅仅只是执行回调函数,还需要处理promise2的状态同步问题)
b. 在等待出发的状态的时候,这个时候状态没有变更,所以还是keep pending状态,而promise2也是pending;当promise触发了resolve,这个时候就需要处理之前订阅的回调了,先改变Promise自身的状态,然后调用callback,将callback的值传入解析函数,同步改变Promise2的状态;触发reject动作和resolve一样
c. 这样,在整个pending链路上,自身状态和promise2状态全都同步改变完成
- resolve 状态
a. Promise内部状态以及变更完毕,内部会存储PromiseValue的值,直接获取PromiseValue的值作为参数,调起then方法传进来的resolveCallback的函数。
b. 使用同步解析函数,去同步改变Promise2的状态,以及后续可then的操作
- reject 状态
该状态操作,同resolve操作,只是变更状态不一样
以上为then方法的所有操作流程,pending的时候最特殊,有个订阅发布设计来改变自身状态,然后同步改变Promise2的状态。其他resolve和reject,都是状态已经变更完毕,直接取状态变更的值,处理回调,然后同步改变Promise2的状态值。这边同步变更Promise2的规则,在A+的规范里是有定义的。
第三张:同步改变Promise2状态以及是否可继续then的操作
状态同步改变和是否可持续then的操作解析流程,都按照A+规范去判断
x代表callback的返回值,首先判断x和Promise2是否相等,相等抛出TypeError的错误(毕竟如果返回值x和Promise2是一个对象的话,那操作就没啥意义了)
判断x是否是Promise对象,如果是的话,说明x是可支持then的,然后根据x的状态进行操作和同步改变Promise2的值,pending就等待执行结束,resolve和reject就分别改变Promise2的状态
如果x不是Promise对象,判断x是否是对象或者function,否的话直接resolve Promise2状态。如果是的话,try-catch捕获,定义then = x.then是否报错,如果报错则reject掉Promise2状态。
判断then是否是function,如果是则执行then操作,如果then方法执行了reject,则reject掉Promise2。
如果then执行resolve,则将y替换掉x,重新和Promise2进行状态的同步改变。
PS:这里的x.then就是下面的这种状况,A+规范定义这样的返回值代表还是可then的,需要处理
temp.then(function (x) {return {then: function(resolve, reject) {resolve(42);}}})
复制代码
至此整个Promise就结束了,从Promise怎么去运行,到核心代码then的处理,以及Promise2的同步改变,这就是所谓的Promise。回过头来发现,最值得佩服的是这种规范的设计思维,通过一种设计思维,将简单的技术化腐朽为神奇。所以,个人意见,程序员的进阶,最重要的不是代码的熟练度,而是思维的进阶。熟练度这个是每个人都可以靠时间堆积出来的,但是更高级的工程师,应该能从整体的视角去了解,然后规划和设计,将简单的技术化神奇,将复杂的问题化简单。
代码可以到 github 上查看,功能完善了,支持all、race、resolve、reject方法
在ajax-js的库的变动,如下:
替换之前有问题的createPromise的代码
将get、post、postForm,obtainBlob,upload进行改造,改方法返回都是Promise(考虑这些都是one-and-done模型,而轮询和大文件切割上传2个方法是持续性操作,所以不做改变)
删除postJSON、promiseAjax方法
ajax-js库增加新功能:mock功能
全局配置参数:
// mock功能
mock: {isOpen: true,mockData: {}
},
复制代码
流程如下:
demo:
// 全局配置
ajax.config({baseURL:'http://localhost:3000/',mock: {isOpen:true,mockData: {'post':'我是mock数据'}}
})// 测试代码
function request_post() {ajax.post('post',{data:'ajaxPost'}).then(x=>{console.warn(x)})
}
复制代码
测试结果:
注意:mockData的key是url的值,不是baseUrl+url的值
结束语:
ajax-js.1.9.2完成了,一直在思考还有什么需要改进的东西,之后的迭代需要走的方向
完成http其他协议,put、delete等等
npm的包面向现代化,去除各种polyfill和一些兼容代码
配置webpack自动打包压缩
探索通信和其他技术的结合玩法
等等...
github地址:github.com/GerryIsWarr… 对你有帮助或启发,点个小星星,支持继续研究下去
转载于:https://juejin.im/post/5cb982e4f265da0368145788
前端通信:ajax设计方案(十)--- 完善Promise A+规范,增加mock数据功能相关推荐
- 云e办学习笔记(二十五)导入导出Excel表数据功能实现
前言 本系列博客基于B站的云e办管理系统,前端和后端我都自己敲了一遍,这里做一个学习记录.云e办的原始视频链接如下:https://www.bilibili.com/video/BV1Ai4y1P7T ...
- 前端简单入门第十八讲 使用jQuery实现表格的隔行换色
还记得之前我使用JavaScript来实现表格的隔行换色效果吗?如果读者初次翻阅本文,可记得看看前端简单入门第十二讲 使用JavaScript完成后台数据展示表格的隔行换色!现在我就来使用jQuery ...
- 前端通信:ajax设计方案(五)--- 集成promise规范,更优雅的书写代码(改迭代已作废,移步迭代10)...
该迭代已作废,最新的请移步这里:https://www.cnblogs.com/GerryOfZhong/p/10726306.html 距离上一篇博客书写,又过去了大概几个月了,这段时间暂时离开了这 ...
- 前端通信:ajax设计方案(三)--- 集成ajax上传技术
在此之前让我感慨一下现在的前端开发的氛围.我遇到好多人,给我的观念都是,这个东西这个框架有了,那个东西那个框架做了,前端嘛,学几个框架,这个拼凑一下那个拼凑一下就好了.其实我想问,东西都框架做了,那你 ...
- 2022前端知识整理:十、vue基础
十.vue基础 2022前端知识整理:第十部分.vue基础,仅包含vue2.0相关知识,建议先完成html5.css3和JavaScript ES6之后再学习.部分图片未上传成功,稍后完善,请见谅. ...
- ajax 取值 返回map_springboot|前端发ajax请求到后台Controller及常见的坑
前端发ajax请求 这块是web的基础,发web请求大概需要以下几步1.引用web相关的依赖2.前端页面引入jquery.js3.编写ajax请求4.编写对应的Controller 引入web相关的依 ...
- 【零基础学Java】—TCP通信(五十四)
[零基础学Java]-TCP通信(五十四) TCP通信:面向连接的通信,客户端和服务器端必须经过三次握手,建立逻辑连接,才能通信(安全). 通信的步骤: 服务器端先启动 服务器端不会主动的请求客户端, ...
- 【手写 Promise 源码】第八篇 - 完善 Promise 并通过 promise-aplus-tests 测试
一,前言 上一篇,实现 Promise 对返回值 x 各种情况的分析和处理,主要涉及以下几个点: 回顾了相关的 Promise A+ 规范内容: 根据 Promise A+ 规范描述和要求,实现了核心 ...
- 新年新气象!新益求新的前端周刊(第十四期)
前端周刊是一份专为前端从业人员,以及对前端.设计领域感兴趣的朋友们打造的技术周刊.程小狮会精选出前端.设计领域近期相关的资讯.热点以及技术干货,与大家一同分享. 前端周刊专注于前端领域技术分享.希望这 ...
最新文章
- L1-044 稳赢 (暴力法)
- Java实现的简单神经网络(基于Sigmoid激活函数)
- php curl 下载网页,php 通过cURL函数抓取网页、下载网页的简单示例
- BugKuCTF 杂项 telnet
- yarn的基本组成和工作流程
- php将excel导入mysql,PHP实现将EXCEL文件导入到MYSQL
- 树存储结构(代码、分析、汇编)
- 一位准程序员对软件行业的8个问题
- log4j.properties的配置与详细说明
- K8S认证、授权与准入控制(RBAC)详解
- 苏州netapp存储服务器维修,NetApp存储日常维护手册 v12.doc
- php视频系统源码,基于ThinkPHP框架仿优酷视频源码带数据,后台功能强大
- 表结构生成html页面,表结构设计器
- 步进电机驱动器单片机控制电路
- linux安装2870无线网卡,告诉你Ubuntu 12.04下RT5370无线网卡驱动安装的方法及命令
- error: Microsoft Visual C++ 14.0 is required. Get it with “Build Tools for Visual Studio“: https://
- 恒生UFX 统一接入介绍
- WinCC V7.2学习记录
- update与upgrade的区别
- STM32F1系列以及CM3内核的时钟与中断内容详解
热门文章
- 4.Ext JS Ext.data.Store本地过滤
- linux系统宿主定制之初窥门径
- mybatis 操作动态表+动态字段+存储过程
- Generic Data Access Objects -范型DAO类设计模式
- 如何使用Ajax技术开发Web应用程序(2)
- 扩展SpringMVC以支持绑定JSON格式的请求参数
- 线程基类的构建与代码实践
- linux内存源码分析 - 内存压缩(同步关系)
- php 不等待返回的实现方法(异步调用)
- Exchange 2010 OAB下载问题排错error 0x80200049