亲自打造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)的角色 ...
随机推荐
- NodeJS笔记(三)-创建第一个NodeJS web项目 Express
参考:Express的安装 先创建一个文件夹专门存放NodeJS项目,这里以“E:\NodeJSProject”为例 CMD指向该目录 执行以下命名 mkdir expressdemo cd expr ...
- C++ 11 多线程下std::unique_lock与std::lock_guard的区别和用法
这里主要介绍std::unique_lock与std::lock_guard的区别用法 先说简单的 一.std::lock_guard的用法 std::lock_guard其实就是简单的RAII封装, ...
- C++(+类型加强 +加入面向对象)
1.c++中所有变量可以在使用前定义. ; i< ; i++) { ; j< ; j++) { do_sth; } } 2. c++ 中可以获得 register 变量的地址. regis ...
- Android ListVeiw控件(转载整理)
列表的显示需要三个元素: 1.ListVeiw 用来展示列表的View. 2.适配器 用来把数据映射到ListView上的中介. 3.数据 具体的将被映射的字符串,图片,或者基本组件. 根据列表 ...
- Django组件——分页器和中间件
分页器 Django内置分页器(paginator) 分页器函数为paginator,里面有几个重要的参数需要我们了解 paginator = Paginator(book_list, 10) #第二 ...
- Python 运维
1.python解释器提供提供的小工具 1.1 一秒钟启动一个下载服务器 进入要下载文件的目录(shift+鼠标右键可以很快的在当前目录打开一个cmd) python2: python2 -m Sim ...
- JDK 1.8源码阅读 LinkList
一,前言 LinkedList是一个实现了List接口和Deque接口的双端链表.有关索引的操作可能从链表头开始遍历到链表尾部,也可能从尾部遍历到链表头部,这取决于看索引更靠近哪一端. LinkedL ...
- Struts2重要知识点总结
一.interceptor拦截器的使用 第一种情况(指定action使用该拦截器):struts.xml文件的配置: <interceptors> <interceptor name ...
- python使用grpc调用rpc接口
proto文件: syntax = "proto3"; package coupon; // //message UnsetUseC2URequest { // int64 bid ...
- Java第二次考试
代码 package sizeyunsuan; import java.io.FileNotFoundException; import java.io.PrintStream; import jav ...