https://segmentfault.com/a/1190000000684654

What?

PromiseCommonJS的规范之一,拥有resolverejectdonefailthen等方法,能够帮助我们控制代码的流程,避免函数的多层嵌套。如今异步在web开发中越来越重要,对于开发人员来说,这种非线性执行的编程会让开发者觉得难以掌控,而Promise可以让我们更好地掌控代码的执行流程,jQuery等流行的js库都已经实现了这个对象,年底即将发布的ES6也将原生实现Promise

Why

想象这样一个场景,两个异步请求,第二个需要用到第一个请求成功的数据,那么我们代码可以这样写

    ajax({
url: url1,
success: function(data) {
ajax({
url: url2,
data: data,
success: function() {
}
});
}
});

如果继续下去在回调函数中进行下一步操作,嵌套的层数会越来越多。我们可以进行适当的改进,把回调函数写到外面

    function A() {
ajax({
url: url1,
success: function(data) {
B(data);
}
});
}
function B(data) {
ajax({
url: url2,
success: function(data) {
......
}
});
}

即使是改写成这样,代码还是不够直观,但是如果有了Promise对象,代码就可以写得非常清晰,一目了然,请看

new Promise(A).done(B);

这样函数B就不用写在A的回调中了

How

目前的ES标准中还未支持Promise对象,那么我们就自己动手,丰衣足食吧。思路大致是这样的,用2个数组(doneListfailList)分别存储成功时的回调函数队列和失败时的回调队列

  • state: 当前执行状态,有pendingresolvedrejected3种取值

  • done: 向doneList中添加一个成功回调函数

  • fail: 向failList中添加一个失败回调函数

  • then: 分别向doneListfailList中添加回调函数

  • always: 添加一个无论成功还是失败都会调用的回调函数

  • resolve: 将状态更改为resolved,并触发绑定的所有成功的回调函数

  • reject: 将状态更改为rejected,并触发绑定的所有失败的回调函数

  • when: 参数是多个异步或者延迟函数,返回值是一个Promise兑现,当所有函数都执行成功的时候执行该对象的resolve方法,反之执行该对象的reject方法
    下面是我的具体实现过程:

var Promise = function() {
this.doneList = [];
this.failList = [];
this.state = 'pending';
}; Promise.prototype = {
constructor: 'Promise',
resolve: function() {
this.state = 'resolved';
var list = this.doneList;
for(var i = 0, len = list.length; i < len; i++) {
list[0].call(this);
list.shift();
}
},
reject: function() {
this.state = 'rejected';
var list = this.failList;
for(var i = 0, len = list.length; i < len; i++){
list[0].call(this);
list.shift();
}
},
done: function(func) {
if(typeof func === 'function') {
this.doneList.push(func);
}
return this;
},
fail: function(func) {
if(typeof func === 'function') {
this.failList.push(func);
}
return this;
},
then: function(doneFn, failFn) {
this.done(doneFn).fail(failFn);
return this;
},
always: function(fn) {
this.done(fn).fail(fn);
return this;
}
}; function when() {
var p = new Promise();
var success = true;
var len = arguments.length;
for(var i = 0; i < len; i++) {
if(!(arguments[i] instanceof Promise)) {
return false;
}
else {
arguments[i].always(function() {
if(this.state != 'resolved'){
success = false;
}
len--;
if(len == 0) {
success ? p.resolve() : p.reject();
}
});
}
}
return p;
}

Improve

目前只是实现了Promise的基础功能,但仍然还有无法处理的情况,例如要实现3个或3个以上的异步请求的串行,目前我的Promise没有办法支持new Promise(A).then(B).then(C)这样的形式,jQuery在1.7的版本中为Deferred(Promise)对象实现了pipe函数,可以通过这个函数实现上述功能,代码为$.Deferred(A).pipe(B).then(C),我尝试去读了jQuery这部分的代码,但是没能读懂,希望有大神能够给一些实现思路

浅谈Javascript中Promise对象的实现的更多相关文章

  1. 浅谈JavaScript中的闭包

    浅谈JavaScript中的闭包 在JavaScript中,闭包是指这样一个函数:它有权访问另一个函数作用域中的变量. 创建一个闭包的常用的方式:在一个函数内部创建另一个函数. 比如: functio ...

  2. 浅谈JavaScript中的null和undefined

    浅谈JavaScript中的null和undefined null null是JavaScript中的关键字,表示一个特殊值,常用来描述"空值". 对null进行typeof类型运 ...

  3. 浅谈JavaScript中的正则表达式(适用初学者观看)

    浅谈JavaScript中的正则表达式 1.什么是正则表达式(RegExp)? 官方定义: 正则表达式是一种特殊的字符串模式,用于匹配一组字符串,就好比用模具做产品,而正则就是这个模具,定义一种规则去 ...

  4. 浅谈Java中的对象和引用

    浅谈Java中的对象和对象引用 在Java中,有一组名词经常一起出现,它们就是“对象和对象引用”,很多朋友在初学Java的时候可能经常会混淆这2个概念,觉得它们是一回事,事实上则不然.今天我们就来一起 ...

  5. 浅谈Java中的对象和对象引用

    浅谈Java中的对象和对象引用 在Java中,有一组名词经常一起出现,它们就是“对象和对象引用”,很多朋友在初学Java的时候可能经常会混淆这2个概念,觉得它们是一回事,事实上则不然.今天我们就来一起 ...

  6. 浅谈JavaScript中的Ajax

    引言 作为一名WEB开发者,我想Ajax技术是一定需要掌握的.你也许平时没有使用JavaScript真正的写过Ajax.但是你一定使用过JQuery里面的相关函数来进行异步调用.今天我们就来介绍下原生 ...

  7. 通过一道笔试题浅谈javascript中的promise对象

    因为前几天做了一个promise对象捕获错误的面试题目,所以这几天又重温了一下promise对象.现在借这道题来分享下一些很基础的知识点. 下面是一个面试题目,三个promise对象捕获错误的例子,返 ...

  8. 浅谈JavaScript中的内存管理

    一门语言的内存存储方式是我们学习他必须要了解的,接下来让我浅谈一下自己对他的认识. 首先说,JavaScript中的变量包含两种两种类型: 1)值类型或基本类型:undefined.null.numb ...

  9. 浅谈JavaScript中闭包

    引言 闭包可以说是JavaScript中最有特色的一个地方,很好的理解闭包是更深层次的学习JavaScript的基础.这篇文章我们就来简单的谈下JavaScript下的闭包. 闭包是什么? 闭包是什么 ...

随机推荐

  1. 理解Miller-Rabbin算法

    转自:http://www.dxmtb.com/blog/miller-rabbin/ 普通的素数测试我们有O(√ n)的试除算法.事实上,我们有O(slog³n)的算法. 定理一:假如p是质数,且( ...

  2. codevs 1488GangGang的烦恼

    题目链接:http://codevs.cn/problem/1488/ 写个高精度大数运算就行 #include<cstdio> #include<iostream> #inc ...

  3. JQ JSON数据类型

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. 常用的Java代码汇总

    1. 字符串有整型的相互转换           Java   1 2 <strong>Stringa=String.valueOf(2);   //integer to numeric ...

  5. Solr auto commit 配置

    为了解决写索引时频繁提交带来的效率问题,考虑使用自动提交. 在solrconfig.xml中增加以下代码: <updateHandler class="solr.DirectUpdat ...

  6. leetcode 1_2_3_7

    来自lknny.com,欢迎交流学习!点击 tags: [leetcode,algorithm] categories: algorithm --- Two Sum Given an array of ...

  7. android AsyncTask介绍(转)

    android AsyncTask介绍 AsyncTask和Handler对比 1 ) AsyncTask实现的原理,和适用的优缺点 AsyncTask,是android提供的轻量级的异步类,可以直接 ...

  8. ORB特征点检测

    Oriented FAST and Rotated BRIEF www.cnblogs.com/ronny   这篇文章我们将介绍一种新的具有局部不变性的特征 -- ORB特征,从它的名字中可以看出它 ...

  9. BZOJ 2152: 聪聪可可 树分治

    2152: 聪聪可可 Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一 ...

  10. git warning: LF will be replaced by CRLF in...

    如果你有git项目,在提交代码的过程中可能会碰到上面的警告,特别是的项目中包含序列化对象的时候,你可能要小心!! 警告的含义是说换行符的,不同的操作系统的换行符是不一致的,如果你不清楚,真得看看这个 ...