亲自打造Deferred对象
经过对比之后,决心学习jQuery,自己打造一个Deferred对象.var util = require('./util.js');function Callbacks() {
var list = [], fireIndex = -1, firing, momery,
self = {
add: function () {
if (list) {
if (firing) {
fireIndex = list.length - 1;
}
(function add(args) {
for (var i = 0; i < args.length; i++) {
var value = args[i];
var type = util.type(value);
if (type === 'function') {
list.push(value);
}
else if (type === 'array') {
add(value);
}
}
})(arguments);
if (!firing && momery) {
this.fire.apply(this, momery);
}
}
return this;
},
remove: function () {
for (var i = 0; i < arguments.length; i++) {
var value = arguments[i];
var index = list.indexOf(v)
if (index > -1) {
list.splice(index, 1);
}
if (index <= firingIndex) {
firingIndex--;
}
}
return this;
},
has: function (fn) {
return fn ?list.indexOf(fn) > -1 :list.length > 0;
},
empty: function () {
if (list) {
list = [];
}
return this;
},
fire: function () {
momery = util.slice.call(arguments);
if (!firing) {
fireing = true;
while (++fireIndex < list.length) {
list[fireIndex].apply(this, momery);
}
list = [];
fireIndex = -1;
}
firing = false;
}
}
return self;
}
function Deferred() {
var state = "pending", scalls = Callbacks(), fcalls = Callbacks(), promise = {
state: function () {
return state;
},
always: function () {
var args=util.slice.call(arguments);
this.done(args).fail(args);
return this;
},
then: function (success, fail) {
switch (state) {
case "resolved":
scalls.add(success);
break;
case "rejected":
fcalls.add(fail);
break;
default:
scalls.add(success);
fcalls.add(fail);
break; }
return this;
},
done: function (success) { this.then(success, null);
return this;
},
fail: function (fail) {
this.then(null, fail);
return this;
},
resolve: function () {
if (state === "pending") {
state = "resolved";
scalls.fire.apply(this, arguments);
}
return this;
},
reject: function () {
if (state === "pending") {
state = "rejected";
fcalls.fire.apply(this, arguments);
}
return this;
}
};
return promise;
}
module.exports = {
Deferred: function () {
return Deferred();
},
when: function () {
var deferred = Deferred(), args = util.slice.call(arguments), ramin = len = arguments.length, context;
function update(i) {
return function (value) {
context[i] = arguments.length > 1?util.slice.call(arguments):value;
if (!--ramin) {
deferred.resolve.apply(deferred, context);
}
}
}
if (len > 0) {
context = new Array(len);
for (var i = 0; i < len; i++) {
var def = args[i];
if (def && util.type(def.then) === 'function') {
def.then.call(def, update(i), deferred.reject);
}
else {
update(i)(def);
}
}
}
return deferred;
}
}
测试用例:
var Q = require('./Deferred.js');
var deferred = Q.Deferred();
setTimeout(function () {
deferred.reject(1).then(function (r) { console.log("r4:" + r); }, function (e) { console.log("e4:" + e); });
}, 5000);
deferred.then(function (r) { console.log("r:" + r); }, function (e) { console.log("e:" + e); });
setTimeout(function () {
deferred.reject(2).then(function (r) { console.log("r2:" + r); }, function (e) { console.log("e2:" + e); });
}, 10000);
deferred.then(function (r) { console.log("r3:" + r); }, function (e) { console.log("e3:" + e); });
function A(){
var d = Q.Deferred().done(function (r) { console.log('A'+r); });
setTimeout(function () {
d.resolve('阿');
}, 1000);
return d;
}
function B() {
var d = Q.Deferred().done(function (r) { console.log('B' +r); /*d.resolve('b');*/ });
return d;
}
function C() {
var d = Q.Deferred().done(function (r) { console.log('C' +r); /*d.resolve('c');*/ });
setTimeout(function () {
}, 1000);
return d;
} Q.when(1, A() , 3).done(function (a,b,c) {
console.log(a);
console.log(b);
console.log(c);
}).fail(function (err) { console.log('err' + err); });
实际应用包装:
var d=require('./lib/deferred');
var util=require('./lib/util');
var mysql = require('mysql');
var settings = require('./config');
exports.process = function (wrappers) {
var con = mysql.createConnection(settings.db);
console.time('process');
con.beginTransaction(function (err) {
if (err) { console.error(err); }
else{
(function (wrappers){
var callee=arguments.callee;
if(util.type(wrappers)=='array'){
function wrapped(wraper){
var deferred= d.Deferred();
con.query(wraper.sql, wraper.data,function(err,rows){
if(err){
deferred.reject(err);
}
else{
deferred.resolve(rows);
}
});
deferred.then(wraper.scall,wraper.fcall);
return deferred;
}
var deferreds=[];
wrappers.forEach(function(wraper,i){
deferreds.push(wrapped(wraper));
});
d.when.apply(null,deferreds).then(function(){
con.commit(function (err) {
if (err) {
console.error(err);
return con.rollback(function () {
con.end(function (err) { if(err){console.error(err);} });
});
}
console.info('process success!');
});
},function(err){
console.error(err);
con.rollback(function () {
con.end(function (err) { if (err) { console.error(err); } });
});
}).always(function () { console.timeEnd('process'); });
}else if(util.type(wrappers)=='object'){
callee([wrappers]);
}
})(wrappers);
}
});
};
亲自打造Deferred对象的更多相关文章
- jquery管理ajax异步-deferred对象
今天跟大家分享一个jquery中的对象-deferred.其实早在jquery1.5.0版本中就已经引入这个对象了.不过可能在实际开发过程中用到的并不多,所以没有太在意. 这里先不说deferred的 ...
- jQuery的deferred对象详解
jQuery的deferred对象详解请猛击下面的链接 http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_ ...
- 【Jquery】$.Deferred 对象
源:http://www.ruanyifeng.com/ deferred三个状态 “已完成”“未完成”“已失败” (1) $.Deferred() 生成一个deferred对象. ...
- jQuery的deferred对象学习
#copy { background-color: lightgreen; padding: 15px; margin: 10px } 一.deferred对象简介 deferred对象是jquery ...
- 【转载】学习资料存档:jQuery的deferred对象详解
我在以前的文章里提到promise和deferred,这两个东西其实是对回调函数的一种写法,javascript的难点之一是回调函数,但是我们要写出优秀的javascript代码又不得不灵活运用回调函 ...
- jQuery的deferred对象使用详解——实现ajax线性请求数据
最近遇到一个ajax请求数据的问题 ,就是想要请求3个不同的接口,然后请求完毕后对数据进行操作,主要问题就是不知道这3个请求誰先返回来,或者是在进行操作的时候不能保证数据都已经回来,首先想到能完成的就 ...
- jQuery的deferred对象详解(转载)
本文转载自: jQuery的deferred对象详解(转载)
- 【转载】jQuery1.5之后的deferred对象详解
原文:http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html 原文作者 ...
- jQuery之Deferred对象详解
deferred对象是jQuery对Promises接口的实现.它是非同步操作的通用接口,可以被看作是一个等待完成的任务,开发者通过一些通过的接口对其进行设置.事实上,它扮演代理人(proxy)的角色 ...
随机推荐
- jsp (二) 练习
package cn.sasa.serv; import java.io.IOException; import java.sql.SQLException; import java.util.Lis ...
- axios实现拦截器
项目中通常使用token进行用户权限认证,需要在请求的header中添加token信息进行验证,拦截返回的状态码进行跳转或重新登陆,在全局配置这些不妥,所以新建一个axios实例进行项目的配置. // ...
- HDU 3033 分组背包(至少选一个)
分组背包(至少选一个) 我真的搞不懂为什么,所以现在就只能当作是模板来用吧 如果有大牛看见 希望评论告诉我 &代码: #include <cstdio> #include < ...
- python_MySQL
原文章连接:http://www.runoob.com/python/python-mysql.html 配置数据库 conn = mysql.connector.connect(user='root ...
- python 全局变量的import机制
在之前学习python设计模式(工厂模式实践篇),希望使用全局变量代替c++的宏完成服务自动注册功能时,遇到过一个问题,全局变量的定义和使用放在同一个可执行脚本中的问题.先把有问题的代码晒一下: IS ...
- OpenStack-Neutron-VPNaaS-配置
配置openstack版本:Juno vpnaas配置的资料很少,官网目前参考的https://wiki.openstack.org/wiki/Neutron/VPNaaS/HowToInstall比 ...
- winfrom进程、线程、用户控件
一.进程 一个进程就是一个程序,利用进程可以在一个程序中打开另一个程序. 1.开启某个进程Process.Start("文件缩写名"); 注意:Process要解析命名空间. 2. ...
- vue mand-mobile ui加class不起作用的问题 css权重问题
vue mand-mobile ui加class不起作用的问题 css权重问题组件的样式优先权比自己定的class高多加几层权重才行,要直接用样式覆盖也可以在前面多加几层class,定位更精确了才会覆 ...
- MySQL更新命令_UPDATE
创建测试表 mysql> CREATE TABLE `product` ( -> `proID` ) NOT NULL AUTO_INCREMENT COMMENT '商品表主键', -& ...
- docker容器与大数据组件的冲突点
1.容器里面安装spark,外面的程序(安装spark主机的容器)会连接不上集群.理由:这个组件用的akka,连接上集群,会提示: akka.ErrorMonitor: dropping messag ...