Promise与异步
不知道promise,大家现在用了吗?如果还不了解的话,今天就来对了~基础的了解起来~
正文从这开始~
接触过promise的的都知道它的应用场景和用途,Promise可以用来避免异步操作函数里的嵌套回调(callback hell)问题,因为解决异步最直接的方法是回调嵌套,将后一个的操作放在前一个操作的异步回调里,但如果操作多了,就会有很多层的嵌套。
Promise的实现方式比较多,有丰富的第三方库,ES6也已经原生支持了Promise,jquery中也有$.Deferred()等可以解决异步嵌套问题。
先给下Promise学术点的描述:
promise代表一个异步操作的执行返回状态,这个执行返回状态在promise对象创建时未必已知。它允许你为异步操作的成功或失败指定处理方法。
这使得异步方法可以像同步方法那样返回值:异步方法会返回一个包含了原返回状态的 promise 对象来替代原返回状态。
一、Promise的适用场景
Promise并非适用于所有的异步场景,例如事件的绑定,某个程度上Promise有点类似事件的监听回调,当触发某个操作时进行后面特定的逻辑。但Promise只能执行一次,且需要前面特定的操作执行完成才会进行下一步,一般分成功和失败两种场景,成功或失败后会立即执行响应函数。这就很适合判断一个比较耗时的操作是否最终执行成功的场景,就如我们通常理解的ajax网络请求、读取localstorage等操作。
二、Promise的表现
如果使用回调方法处理多个操作的异步场景,判断某个操作成功或失败的控制在于声明的匿名函数里面,使用Promise对象则可以重新定义异步执行的状态和控制逻辑。
promises的最重要的特点就是它把我们处理任何函数调用的成功或者失败的方式规范成了可预测的形式,特别是如果这个调用实际上的异步的。
Promise中有几个状态:
pending: 初始状态。 非 fulfilled 或 rejected。
resolved: 成功的操作。也有的成为fulfilled 。
rejected: 失败的操作。
不同的Promise差异基本表现如下:
构造Promise对象 new Promise().resolve() 或者newPomise(function(resolve, reject) {})
是否有 .done().fail().always() 等方法
是否有Promise.all()方法
是否有isRejected()isResolved()
.then() return 结果链式的
三、几种规范的promise
2.1、Promise的Promise/A 规范和Promise/A+规范
先看下规范的地址:http://wiki.commonjs.org/wiki/Promises/A https://promisesaplus.com/
什么是A+规范的Promise? Promises/A+是在Promises/A的基础上对原有规范进行修正和增强。
Promise A+与Promise A的主要区别:
符合Promise/A+规范的promise实现均以then方法为交互核心。Promises/A+组织会因新发现的问题以向后兼容的方式修改规范,因此Promises/A+规范相对来说还是比较稳定的。
A+规范强调了不同实现之间的互操作和混用,通过术语thenable来区分promise对象,当一个对象拥有then函数就认为是promise对象
A+定义当onFulfilled或者onRejected返回promise时后的处理过程,他们必须是作为函数来调用,而且调用过程必须是异步的
A+严格定义了then方法链式调用时onFulfilled或者onRejected的调用顺序
目前判断是否为Promise/ A+规范主要看Promiise的方法含有new Pomise(function(resolve,reject){})、then、resolve、all等方法。ES6 Promise的实现严格遵循了Promise/A+规范。例如Defferd就不是Promise/ A+的规范。
2.2、Defferd实现规范
比较典型的是jquery的Defferd方法实现的Promise,另外jquery还有一个Promise的类型,实现的原理相同,但是不遵循Promise/A+规范,相对于Promise没有那么稳定。
我们先来看看jquery的Promise是怎样实现的。我们看下jquery的Deferred实现源码:
可见,jquery的Deferred是个工厂类,返回的是内部构建的deferred对象;tuples 含有三个$.Callbacks对象,分别表示成功,失败,处理中三种状态;创建的promise对象,具有state、always、then、primise方法;扩展primise对象生成最终的Deferred对象,返回该对象;没有resolve、reject、all等Promise/A+ 规范的常用方法。
四、兼容性
目前使用需要使用polyfill,也就是原生实现一个Promise支持较低浏览器,第三方实现库很多后面给了个学习的较好例子。
五、generator的异步
Promise处理异步问题相信都了解了。ES6里的generator还有另一个处理异步的方法,那ES6定义这两个特性岂不是重复了?
单独地介绍Generator没有太大价值,因为它除了更复杂外,功能与普通函数没有太大差别。真正让Generator具有价值的是yield关键字,这个yield关键字让Generator内部的逻辑能够切割成多个部分。并且可以灵活控制内部的执行情况。
运行时使用node–harmony-generatorstest.js
不难发现它的运行过程,generator函数运行到yield时会停止,等待下一个next()方法调用让它继续执行。我们改下成为异步方法,异步我们需要借助高阶函数
那么后面的写法做下修改
generator实现异步的方法也有比较完整的封装方式,实现先可以看:https://github.com/ouvens/co 可以看个简单版的:
我们小结一下通过Generator进行流程控制的特点。 - 每个异步方法都需要标准化为yield关键字能接受的方法,使我们有机会注入特殊逻辑,这个过程被称为thunkify。 - 需要巧妙地将异步调用执行完成得到的结果通过.next()传递给下一段流程。 - 需要递归地将业务逻辑执行完成。
需要注意的是yield只能暂停Generator内部的逻辑,它并不是真正暂停整个线程,Generator外的业务逻辑依然会继续执行下去。
六、总结
实现异步的方法目前有,自定义嵌套,Promise、generator、Defferd,还有ES7的async(其实是generator的封装),不同场景可以选择不同的方式去实现
简单的Promise实现样例: https://github.com/ouvens/promise
generator异步实现: https://github.com/tj/co
后语
这篇只是大概介绍了下,可以通过这篇大家自行自主搜索详细内容。
Promise与异步的更多相关文章
- Angular JS 学习笔记(自定义服务:factory,Promise 模式异步请求查询:$http,过滤器用法filter,指令:directive)
刚学没多久,作了一个小项目APP,微信企业号开发与微信服务号的开发,使用的是AngularJS开发,目前项目1.0版本已经完结,但是项目纯粹为了赶工,并没有发挥AngularJS的最大作用,这几天项目 ...
- Promise和异步编程
前面的话 JS有很多强大的功能,其中一个是它可以轻松地搞定异步编程.作为一门为Web而生的语言,它从一开始就需要能够响应异步的用户交互,如点击和按键操作等.Node.js用回调函数代替了事件,使异步编 ...
- ES6 Promise 让异步函数顺序执行
应用 ES6 的 内置对象 Promise, 让异步函数 按顺序执行的例子 如下: 上边 是四个用Promise 处理过的 异步执行的函数: fn1.fn2.fn3.fn4 下面,让其按顺序执行 如下 ...
- Promise对象 异步编程
Promise 的含义 Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大.所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是 ...
- Node.js用ES6原生Promise对异步函数进行封装
Promise的概念 Promise 对象用于异步(asynchronous)计算..一个Promise对象代表着一个还未完成,但预期将来会完成的操作. Promise的几种状态: pending:初 ...
- jquery.Deferred promise解决异步回调
我们先来看一下编写AJAX编码经常遇到的几个问题: 1.由于AJAX是异步的,所有依赖AJAX返回结果的代码必需写在AJAX回调函数中.这就不可避免地形成了嵌套,ajax等异步操作越多,嵌套层次就会越 ...
- Promise 让异步更优
每个异步方法都返回一个Promise 更优雅. then方法 每一个Promise 都有一个叫then 的方法, 接受一对callback 被解决时调用,resolve, 被拒绝 reje ...
- Promise async-await 异步解决方案
1.简介: async和await在干什么,async用于申明一个function是异步的,而await可以认为是async wait的简写,等待一个异步方法执行完成. 2.基本语法 在C ...
- javascript基础修炼(7)——Promise,异步,可靠性
开发者的javascript造诣取决于对[动态]和[异步]这两个词的理解水平. 一. 别人是开发者,你也是 Promise技术是[javascript异步编程]这个话题中非常重要的,它一度让我感到熟悉 ...
随机推荐
- 原生的Ajax的实现
<script type="text/javascript"> // Ajax固定的模版 // 第一步:创建xhr对象,使用new关键字来调用内置的构造函数 var x ...
- com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'portal.hibernate_sequence' doesn't exist, 谈谈主键自增的方式
最近几天几天做项目用到了Spring Data JPA,确实是个好东西,省了很多力气.但是由于刚开始用,也遇到不少头疼的问题,如下,调用JpaRepository接口的save方法保存一个对象到数据库 ...
- jquery中append与appendTo方法区别
1. append(content)方法 方法作用:向每个匹配的元素内部追加内容. 参数介绍:content (<Content>): 要追加到目标中的内容. 用法示例: HTML代码为& ...
- Kinect 常用识别手势
以下手势能被流畅的识别: ◎RaiseRightHand / RaiseLeftHand – 左手或右手举起过肩并保持至少一秒 ◎Psi –双手举起过肩并保持至少一秒 ◎Stop – 双手下垂. ◎W ...
- 详解Android Activity---启动模式
相关的基本概念: 1.任务栈(Task) 若干个Activity的集合的栈表示一个Task. 栈不仅仅只包含自身程序的Activity,它也可以跨应用包含其他应用的Activity,这样有利于 ...
- ASP.NET Core 开源论坛项目 NETCoreBBS
ASP.NET Core 轻量化开源论坛项目,ASP.NET Core Light forum NETCoreBBS 采用 ASP.NET Core + EF Core Sqlite + Bootst ...
- linux+windows mysql导入导出sql文件
linux下 一.导出数据库用mysqldump命令(注意mysql的安装路径,即此命令的路径):1.导出数据和表结构:mysqldump -u用户名 -p密码 数据库名 > 数据库名.sql# ...
- 导出EXCEL遇到问题
EXCEL设置的格式要与写入信息的格式要匹配,比如写入信息是字符串类型,而EXCEL单元格是DATE类型则会出错.
- (转)Spring boot——logback.xml 配置详解(三)<appender>
文章转载自:http://aub.iteye.com/blog/1101260,在此对作者的辛苦表示感谢! 1 appender <appender>是<configuration& ...
- 读Zepto源码之Deferred模块
Deferred 模块也不是必备的模块,但是 ajax 模块中,要用到 promise 风格,必需引入 Deferred 模块.Deferred 也用到了上一篇文章<读Zepto源码之Callb ...