亲自打造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)的角色 ...
随机推荐
- 查看Sql Server 数据库的内存使用情况
-- 查询SqlServer总体的内存使用情况 select type , sum(virtual_memory_reserved_kb) VM_Reserved , sum(virtual_memo ...
- Centos7+python3.6+face-recognition
Step1 安装Python3.6.xhttps://www.digitalocean.com/community/tutorials/how-to-install-python-3-and-set- ...
- 3、jeecg 笔记之 模糊查询
1.前言 jeecg 考虑到默认模糊查询的话,会增加系统压力,导致查询慢,本来系统就挺那啥的... 2.方式一之实体赋值 实体重新赋值查询,用 * %% * 实现,我们知道 sql 中通常使用 % 去 ...
- java框架之SpringBoot(13)-检索及整合Elasticsearch
ElasticSearch介绍 简介 我们的应用经常需要使用检索功能,开源的 Elasticsearch 是目前全文搜索引擎的首选.它可以快速的存储.搜索和分析海量数据.SpringBoot 通过整合 ...
- python基础(7)-函数&命名空间&作用域&闭包
函数 动态参数 *args def sum(*args): ''' 任何参数都会被args以元组的方式接收 ''' print(type(args)) # result:<class 'tupl ...
- Centos下,Docker部署Yapi接口管理平台(详细得令人发指)
接口测试的工具很多,公司引进了接口管理平台Yapi,自己尝试直接搭建,从安装Nodejs到配置MongoDB数据库,再到安装yapi的时候,遇到浏览器打开本地服务器Ip地址后,没有显示部署内容...没 ...
- 墨刀联合有赞Vant组件库,让你轻松设计出电商原型
继上周新上线了简历模板之后,本周墨刀的原型模板库又欢喜地增添一名新成员! 有赞Vant组件库 (做电商的宝宝要捂嘴笑了) Vant 组件库是有赞前端团队开源的一套基于Vue的UI组件库,目前版本收 ...
- 彻底解决(Microsoft Visual C++ 14.0 is required)的步骤123
之前要用协程gevent,安装pip install gevent包时遇到Microsoft Visual C++ 14.0 is required的报错提示,各种下载没有解决很头疼, 前两天安装sc ...
- CentOS7+Apache+MySQL+PHP环境
Apache 1.安装Apache:yum -y install httpd 2.开启apache服务:systemctl start httpd.service 3.设置apache服务开机启动:s ...
- Linux进程相关命令使用场景
Linux进程相关命令使用场景 在Linux系统上工作时,我们常常会碰到很多和进程相关的查询场景,今天在这里进行详细的讲解,进程相关的对象包括以下几个: 端口:Port 进程号:PId 执行文件所在路 ...