• 亲自打造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);
            }
        });
    };
  • 相关阅读:
    XML中<beans>中属性概述
    (转)深入理解Java:注解(Annotation)自定义注解入门
    maven 配置参数详解!
    maven setting.xml文件配置详情
    hashMap与 hashTable , ArrayList与linkedList 的区别(详细)
    jdbc参数
    linux下ftp命令的安装与使用
    java中的Iterator与增强for循环的效率比较
    命令行窗口常用的一些小技巧
    在eclispe的类中快速打出main方法
  • 原文地址:https://www.cnblogs.com/kingge/p/5427994.html
Copyright © 2020-2023  润新知