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状态改变后 ...
随机推荐
- js中的SetTimeOut
1. SetTimeOut() 1.1 SetTimeOut()语法例子 1.2 用SetTimeOut()执行Function ...
- angularjs于directive声明scope说明何时以及如何使用对象修饰符
于angular我们定义directive方法.查看 return { restrict: 'AE', scope: {}, template: '<div></div>', ...
- python使用正則表達式
python中使用正則表達式 1. 匹配字符 正則表達式中的元字符有 . ^ $ * + ? { } [ ] \ | ( ) 匹配字符用的模式有 \d 匹配随意数字 \D 匹配随意非 ...
- 《UNIX网络编程》之select IO
select 函数的原理 select 管理者 用select来管理多个IO 一旦其中的一个或者多个IO检测到我们所感兴趣的事件, select 函数返回,返回值为检测到的事件个数 然后,遍历事件,进 ...
- Android(java)学习笔记256:JNI之NDK的概念
1.交叉编译 (1)概念 在一个平台(硬件)和os(软件)环境下,编译出另一种平台和os下可以运行的二进制代码. e.g: 电脑端 ...
- 计算方法(一)用C#实现数值迭代
平时,经常会遇到解方程,计算方法中常用的有二分法(精度太低,迭代次数多,一般没人用),牛顿迭代法,弦截法,网上大多都是C++或者Java的实现代码,很少有C#的,我在本科毕业论文中用到了这些,那时也需 ...
- OD: Windows Kernel Debug
内核调试入门 内核程序运行在内核态,因此不能像对用户态应用程序那样来调试.关于内核调试方面的知识请参考<软件调试>这本书.目前内核调试主要有以下三种方法. 一是使用硬件调试器,它通过特定的 ...
- Asp.Net WebApi Action命名中已‘Get’开头问题
ApiController 中的Action 命名已‘Get’开头,Post方法提交失败 场景: 1.action命名使用Get开头 /// <summary> /// 获取用户的未读消息 ...
- 关于导出oracle多个表的建表语句DLL,生成.sql语句。
--('TABLE','LINE','ODS_XX')这里面的表和用户都需要大写.如果表名用户名不大写会报这个错误:对象 "emp" 属于类型 TABLE, 在方案 "s ...
- XIB自定义视图的整理
- (void)setAppInfo:(AppInfo *)appInfo { _appInfo = appInfo; _icon.image = appInfo.image; _label.text ...