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异步编程]这个话题中非常重要的,它一度让我感到熟悉 ...
随机推荐
- 关于Win7 内存变小处理方法
windows + R 输入msconfig 点击引导 点击高级选项 点击最大内存打钩,就好了,你重启,你的内存将恢复成原来的.
- 从源码的角度看Service是如何启动的
欢迎访问我的个人博客 ,原文链接:http://wensibo.top/2017/07/16/service/ ,未经允许不得转载! 七月中旬了,大家的实习有着落了吗?秋招又准备的怎么样了呢?我依旧在 ...
- java基础06 Java中的递归
一.递归是指直接或间接地调用自身. 二.递归的注意事项: A:要有出口,否则就是死递归 B:次数不能过多,否则内存溢出 C:构造方法不能递归使用 三.举例子 递归 ...
- codeforces 129B students and shoes
https://vjudge.net/problem/CodeForces-129B 题意: 有n个学生,他们之间被鞋带缠住了.现在,老师首先把所有只与一个学生直接相连的学生找出来,让他们聚集到一起, ...
- Linux服务器下对Oracle作Rman备份
由于工作需要,最近要对几台Linux系统下的Oracle数据库进行Rman备份,就在操作的同时,整理了一下,方便今后作为资料进行查阅. ------------------------Linux服务器 ...
- js模块加载之AMD和CMD
当我写这篇文章的时候,sea.js已经逐渐退出历史的舞台,详细链接.不过任何新事物的出现都是对旧事物的取其精华,去其糟粕,所以了解一下以前模块的加载也是一件好事. js模块化的原因自不比多说,看看HU ...
- MyBatis 框架的搭建和配置
MyBatis是支持定制化SQL.存储过程以及高级映射的优秀持久层框架.MyBatis 避免了几乎所有的JDBC代码和手动设置参数以及获取结果集.MyBatis可以对配置和原生Map使用简单的xml或 ...
- PHPsthdy+xdebug
PHPsthdy下载后查看phpinfo后会发现没有xdebug这一项: 1.phpStudy集成了XDebug扩展,所以不用单独下载XDebug. 2.打开XDebug扩展:右击PHPstudy的图 ...
- Android学习笔记-EditText(输入框)(一)
1.设置默认提示文本 默认提示文本的两个属性如下: android:hint="默认提示文本" android:textColorHint="#95A1AA" ...
- Linux 下实时查看日志
Linux 下实时查看日志 cat /var/log/*.log 如果日志在更新,如何实时查看 tail -f /var/log/messages 还可以使用 watch -d -n 1 cat /v ...