promise原理浅析
来源:互联网 发布:药智数据网 编辑:程序博客网 时间:2024/05/29 17:50
Promise超神超简单总结:
之前总感觉promise很神秘,今天仔细读了阮一峰大神的es6,也查询了下相关的promise原理,终于明白了promise怎么这么6.
简介:
Promise 对象用于延迟(deferred) 计算和异步(asynchronous )计算.一个Promise对象代表着一个还未完成,但预期将来会完成的操作。Promise 对象是一个返回值的代理,这个返回值在promise对象创建时未必已知。它允许你为异步操作的成功或失败指定处理方法。 这使得异步方法可以像同步方法那样返回值:异步方法会返回一个包含了原返回值的 promise 对象来替代原返回值。
解决了什么问题及怎么使用:
//一个简单的示例 执行一个动画A,执行完之后再去执行另一个动画B setTimeout(function(){ //A动画 console.log('A'); setTimeout(function() { //B动画 console.log('B'); },300) },300);//这里只有两个动画,如果有更多呢,就会看到一堆函数缩进
不难想象,如果依次有很多个动画,就会出现多重嵌套。代码不是纵向发展,而是横向发展,很快就会乱成一团,无法管理。因为多个异步操作形成了强耦合,只要有一个操作需要修改,它的上层回调函数和下层回调函数,可能都要跟着修改。这种情况就称为回调函数地狱“(callback hell)。
Promise 对象就是为了解决这个问题而提出的。它不是新的语法功能,而是一种新的写法,允许将回调函数的嵌套,改成链式调用。
Promise 的最大问题是代码冗余,原来的任务被 Promise 包装了一下,不管什么操作,一眼看去都是一堆then,原来的语义变得很不清楚。
(1)浏览器实现方式 可以在支持Promise的版本上运行
var p = new Promise(function(resolve, reject){ setTimeout(function(){ //A动画 console.log('A'); resolve(); },300);});p.then(function(){ setTimeout(function() { //B动画 console.log('B'); },300);});
(2)另一种写法(jQuery版本)
var deferred = $.Deferred();setTimeout(function(){ //A动画 console.log('A'); deferred.resolve();},300);deferred.done(function() { setTimeout(function() { //B动画 console.log('B'); },300)});
promise会让代码变得更容易维护,像写同步代码一样写异步代码。
promise原理
其实,promise就是三个状态。利用观察者模式,只需要通过特定书写方式注册对应状态的事件处理函数,然后更新状态,调用注册过的处理函数即可。
这个特定方式就是then,done,fail,always…等方法,更新状态就是resolve、reject方法。
下面简单实现:
/** /** * [3种状态] * @type {String} */ var PENDING = "pending"; var RESOLVED = "resolved"; var REJECTED = "rejected"; /** * [Promise类实现] * 构造函数传入一个fn,有两个参数,resolve:成功回调; reject:失败回调; * state: 状态存储 * doneList: 成功处理函数列表 * failList: 失败处理函数列表 * done: 注册成功处理函数 * fail: 注册失败处理函数 * then: 同时注册成功和失败处理函数 * always: 一个处理注册到成功和失败,都会调用 * resolve: 更新state为:RESOLVED,并且执行成功处理队列 * reject: 更新state为:REJECTED,并且执行失败处理队列 */ var Promise2 = (function() { var noop = function() {} function Promise(fn) { this.state = PENDING; this.doneList = []; this.failList = []; this.fn = fn; this.fn(this.resolve.bind(this), this.reject.bind(this)) //立即执行构造函数的第一个参数 } var p = { done: function(cb) { if (typeof cb == "function") this.doneList.push(cb) return this; }, fail: function(cb) { if (typeof cb == "function") this.failList.push(cb); return this; }, then: function(success, fail) { this.done(success || noop).fail(fail || noop) return this; }, always: function(cb) { this.done(cb).fail(cb) return this; }, resolve: function() { this.state = RESOLVED; var lists = this.doneList; for (var i = 0; i < lists.length;) { lists[i].apply(this, arguments); lists.shift(); } return this; }, reject: function() { this.state = REJECTED; var lists = this.failList; for (var i = 0; i < lists.length;) { lists[0].apply(this, arguments); lists.shift(); } return this; } } for (var k in p) { Promise.prototype[k] = p[k] } return Promise; })();//测试代码var p1 = new Promise2(function(resolve,reject){ setTimeout(resolve,2000); console.log('p1',new Date); }); p1.then(function(){ console.log("end",new Date); }).always(function(){ console.log('always',new Date); });
利用观察者模式,只需要通过特定书写方式,注册对应状态的事件处理函数,然后更新状态,调用注册过的处理函数即可。
解释:当我们调用new Promise(fn)时,就会立即执行第一个参数fn。上面案例中,先将then(done,fail)对应的回调函数分别加入到doneList或者failList中,always中对应的参数同时加到doneList和failList中,当异步代码执行完毕,就调用resolve方法,此时改变promise的状态为resolved,并执行doneList里面的回调函数。如果执行失败,则调用fail方法,此时改变promise的状态为rejected,并执行failList里面的回调函数。
4、generator的一个小应用
function * gen(m,n){ for(let i=m;i<n;i++){ yield i; }}console.log(...gen(1,10));//结果: 1 2 3 4 5 6 7 8 9
参考链接:
Promise: http://imweb.io/topic/565af932bb6a753a136242b0
- promise原理浅析
- Promise原理
- ES6 Promise 浅析
- 浅析Promise用法
- Promise实现原理
- Promise原理分析一
- Promise原理分析二
- promise的实现原理
- Promise的实现原理
- Promise介绍--异步原理
- 解析 Promise 原理,实现一个Promise
- node Promise/Deffered原理解析
- Promise浅析(一)——基础篇
- promise实现原理的源码分析
- promise
- Promise
- Promise
- Promise
- 神经网络算法
- VIM备忘
- LinkedList遍历效率
- 数据结构实验之二叉树三:统计叶子数
- uvalive 3938 Ray, Pass me the dishes!(线段树)
- promise原理浅析
- 修改用户信息填写规则
- C++设计模式——Proxy模式
- LIS-最长上升子序列
- 三年PHP面试总结
- 关于RecyclerView的java.lang.IllegalStateException: The specified child already has a parent. You must c
- 未来将更准确!VAR裁判技术引入足球杯
- JS实现滚动监听以及滑动到顶部【转】
- F