Javascript Promise 学习 (中)
时隔多日,对promise有了多一点点的了解。
最近用angularjs 做开发,所以研究了一下它的 $q
功能不算很强大,算是简化版的 Q.js
参考了一下源码,不过我的等级还差很多...
作为学习,我自己又重写了一篇。
这次的比较整齐。代码也少了 .
$q = function (asyncFn) {
var defer = new Deferred();
asyncFn(defer.resolve.bind(defer), defer.reject.bind(defer));
return defer.promise;
};
$q.defer = function () {
return new Deferred();
};
$q.reject = function (reason) {
var defer = new Deferred();
defer.reject(reason);
return defer.promise;
};
$q.all = function (values) {
var defer = new Deferred();
var finalDatas = [];
var count = 0;
values.forEach(function (value, i) {
count++;
$q.when(value, function (data) {
finalDatas[i] = data; //直接按index装入,不用另外排序
if (--count === 0) { //一个++ 一个-- 互相抵消
defer.resolve(finalDatas);
}
}, function (reason) {
defer.reject(reason);
});
});
return defer.promise;
};
$q.when = function (value, onFulfilled, onRejected, onNotify) {
if (value instanceof Promise) return value.then(onFulfilled, onRejected, onNotify);
var defer = new Deferred();
defer.resolve(value);
return defer.promise.then(onFulfilled, onRejected, onNotify);
};
function Deferred() {
this.promise = new Promise();
}
Deferred.prototype = {
//resolve reject 几乎是一样的, notify 在调用后不会被删除
resolve: function (data) {
var promise = this.promise;
//要延误执行,防止then方法还没有设置好回调,就想要resolve的情况
setTimeout(function () {
promise.states = "fulfilled";
promise._processCallback(data);
}, 0);
},
reject: function (reason) {
var promise = this.promise;
setTimeout(function () {
promise.states = "rejected";
promise._processCallback(reason);
}, 0);
},
notify: function (data) {
var promise = this.promise;
setTimeout(function () {
promise.states = "notify";
promise._processCallback(data, true);
}, 0);
},
constructor: Deferred
}
//主要是保存defer, 做promise连用
function Callback(defer, onFulfilled, onRejected, onNotify) {
this.defer = defer;
this.onFulfilled = onFulfilled;
this.onRejected = onRejected;
this.onNotify = onNotify;
}
function Promise() {
this.states = "pending";
this.value = undefined;
this.reason = undefined;
this._callbacks = [];
}
Promise.prototype = {
then: function (onFulfilled, onRejected, onNotify) {
//把回调收集起来,如果states不是等待就马上出发
var defer = new Deferred();
this._callbacks.push(new Callback(defer, onFulfilled, onRejected, onNotify));
if (this.states !== "pending") {
var data = (this.states === "fulfilled") ? this.value : this.reason;
this._processCallback(data);
}
return defer.promise;
},
"catch": function (onRejected) {
return this.then(null, onRejected);
},
'finally': function (cleanup) {
return this.then(cleanup, cleanup);
},
_processCallback: function (data, is_keepCallback) {
//这里的data不接受promise,偷懒没做。哈哈
var promise = this;
if (this.states === "pending") return;
var states = ("on-" + this.states).toCamelCase();
var promiseCallbacks = this._callbacks;
var length = promiseCallbacks.length;
for (var i = 0, l = promiseCallbacks.length; i < l; i++) {
var callback = (is_keepCallback) ? promiseCallbacks[i] : promiseCallbacks.shift();
var defer = callback.defer;
if (G.isFunction(callback[states])) {
//要做错误处理哦
try {
//调用回调,
var returnValue = callback[states](data);
//如果是promise那就乾坤大挪移把promise连连接过去
if (returnValue instanceof Promise) {
returnValue.then(defer.resolve.bind(defer), defer.reject.bind(defer));//这里要用bind,因为resolve内需要引用this
}
else {
//不是的话就到值传给下一个promise咯
defer.resolve(returnValue);
}
}
catch (e) {
defer.reject(e);
}
}
else {
//data不是函数就直接传下去
defer.resolve(data);
}
}
},
constructor: Promise
}
Javascript Promise 学习 (中)的更多相关文章
- Javascript Promise 学习笔记
1. 定义:Promise是抽象异步处理对象以及对其进行各种操作的组件,它把异步处理对象和异步处理规则采用统一的接口进行规范化. 2. ES6 Promises 标准中定义的API: ...
- Javascript - Promise学习笔记
最近工作轻松了点,想起了以前总是看到的一个单词promise,于是耐心下来学习了一下. 一:Promise是什么?为什么会有这个东西? 首先说明,Promise是为了解决javascript异步编 ...
- Javascript Promise 学习(上)
Promise 就是处理异步的一个规范方法 a();b();alert("a");如果a() 里面有一个ajax 或者settimeout 那么alert("a" ...
- JavaScript语言学习中的注意事项
javascript: 基于浏览器 基于对象 事件驱动 脚本语言 由: javascript: ECMAscript(ES) DOM文档对象模型 BOM浏览器对象模型,三部分组成 使用js的三种方式 ...
- 【JavaScript】学习中遇到的一些问题
一.JavaScript中没法直接比较两个object和array是否相等
- JavaScript之Promise学习笔记
一直想知道Promise到底是怎么实现的,网上一搜几十篇文章,看的一脸蒙蔽.最后算是找到几个讲的真心很详细明了的.看了一份源码看了很久很久……最后找大佬问了几处看不懂的地方,大佬只看了十几分钟就看懂了 ...
- JavaScript学习中的挑战
当人们尝试学习 JavaScript , 或者其他编程技术的时候,常常会遇到同样的挑战: 有些概念容易混淆,特别是当你学习过其他语言的时候.很难找到学习的时间(有时候是动力).一旦当你理解了一些东西的 ...
- javascript学习中自己对作用域和作用域链理解
在javascript学习中作用域和作用域链还是相对难理解些,下面我关于javascript作用域和作用域链做一下详细介绍,给各位初学者答疑解惑. 首先我们介绍一下什么是作用域? 从字面上理解就是起 ...
- es6中的Promise学习
关于Promise Promise实例一旦被创建就会被执行 Promise过程分为两个分支:pending=>resolved和pending=>rejected Promise状态改变后 ...
随机推荐
- cannot be resolved to a type in same package 问题解决
在 STS 上,一个类引用在相同 package 中另一个类,但是报 cannot be resolved to a type 错误. 解决方法 : Alternatively, you can hi ...
- C++编写ATM(1)
// ATM的初始.cpp : 定义控制台应用程序的入口点. // /************************************************* 运行环境: VS2008 作者 ...
- [转]百度地图点聚合MarkerClusterer移动地图时,Marker的Label丢失的问题
参考文献:http://www.cnblogs.com/jicheng1014/p/3143859.html 问题现象: 使用MarkerClusterer_min.js,可以实现点聚合,但是当将带有 ...
- Linux内核-内核线程
线程分类:内核线程.用户线程(指不需要内核支持而完全建立在用户空间的线程库,这种线程效率高,由于Linux内核没有轻量级进程(线程)的概念,因此不能独立的对用户线程进行调度,而是由一个线程运行库来组织 ...
- HDU1007 Quoit Design 【分治】
Quoit Design Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...
- [Angular 2] Using Two Reducers Together
Add another reducer: export const SECOND = "SECOND"; export const HOUR = "HOUR"; ...
- Android学习–Android app 语言切换功能
功能: app用户根据自己的语言喜好,设置app语言.语言设置只针对本app,并在下次启动应用时保留前一次启动设置. 更新语言: public static void changeAppLanguag ...
- Windows Server 2008 R2 搭建FTP服务
一.安装ftp服务 1.在服务管理器"角色"右键单击"添加角色". 2.下一步. 3.勾选"Web 服务器(IIS)",下一步. 4.勾选 ...
- U1总结
import java.io.Writer; import java.util.Iterator; import javax.xml.transform.TransformerFactory; imp ...
- vim 学习笔记
vim介绍:一款编辑器,另外一般linux系统会自带,所以一般linux下日志.配置文件等 纯文本文件的修改编辑等通过vim操作 学会的好处:1 方便操作linux下日志.配置文件等纯文本文件 2 功 ...