0

0

0

修罗

站点介绍

只有了解事实才能获得真正的自由

js设计模式(下)

修罗 2020-10-05 1550 0条评论 JS

首页 / 正文

js设计模式(下)

链模式

​ 链模式是实现链式调用的主要方法,通过在自身方法中返回自身的方式,在一个对象连续多次调用自身方法可以简化写法。这种链式调用在很多库和框架如jquery/zepto中频繁的被使用。

1602043646224.png

委托模式

当多个对象需要处理同一请求时,可以将这些请求交由另一个对象统一处理。

例:事件委托

1602045811140.png

数据访问对象模式

​ 数据访问对象模式主要是用来抽象和封装一个对象来对数据源进行访问和存储,这样可以方便对数据的管理,以及避免数据间重复,覆盖等问题出现。

例:定义一个保存数据的方法

/**
* {
*  nameSpace|key: expire|value
* }
*/
var DataVisitor = function(nameSpace, splitSign){
    // nameSpace用来拼接key
    this.nameSpace = nameSpace
    this.splitSign = splitSign || '|';
}

DataVisitor.prototype = {
    status: {
        SUCCESS: 0, 
        FAIL: 1,
        // 溢出
        OVERFLOW: 2,
        TIMEOUT: 3
    },
    // 拼接一个key
    getKey: function(key){
        return this.nameSpace + this.splitSign + key
    },
    // 存储键值对到localStorage
    set: function(key, value, fn, expire){
        var status = this.status.SUCCESS
        key = this.getKey(key)
        expire = typeof expire === 'number' ? expire + Date.now() : -1
        try {
            window.localStorage.setItem(key, expire + this.splitSign + value)
        } catch (error) {
            status = this.status.OVERFLOW
        }
        fn && fn.call(this, status, key, value)
        return value;
    },
    // 读取
    get: function(key, fn){
        key = this.getKey(key)
        this.status = this.status.SUCCESS
        var value = window.localStorage.getItem(key)
        if(value){
            var index = value.indexOf(this.splitSign)
            time = value.slice(0, index)
            if(time > new Date().getTime() || -1){
                value = value.slice(index + this.splitSign.length)
            }else{
                value = null
                status = this.status.TIMEOUT
                window.localStorage.removeItem(key)
            }
        }else{
            status = this.status.FAIL
        }
        fn && fn.call(this, status, key, value)
        return value
    },
    // 删除
    remove: function(key){
        var status = this.status.FAIL
        key = this.getKey(key)
        value = window.localStorage.getItem(key)
        if(value){
            status = this.status.SUCCESS
            window.localStorage.removeItem(key)
        }
        return status
    }
}
// 测试
var learnInfo = new DataVisitor('learn')
learnInfo.set('ok', 'value')

等待者模式

通过对多个异步进程的监听,对未来事件进行统一管理。

例:实现waiter对象调用when传异步事件,返回值调用done或fail执行回调函数

  • waiter.when(异步事件1,异步事件2...).done(fn).fail(fn)
function Waiter(){
    // 存放异步事件
    var dfd = [];
    // 存放成功的回调
    var doneArr = [];
    // 存放失败的回调
    var failArr = [];

    // 保存Defer
    this.when = function(){
        // 获取arguments是类数组对象
        dfd = Array.from(arguments)
        // 删除不满足条件的Defer
        for(var i = dfd.length - 1; i >= 0; i--){
            var d = dfd[i];
            if(!d || d.rejected || d.resolved || !(d instanceof Defer)){
                dfd.splice(i, 1)
            }
        }
        return this;
    }

    // 保存成功的回调
    this.done = function(){
        // 拿到参数(成功回调)
        var args = Array.prototype.slice.call(arguments)
        doneArr = doneArr.concat(args);
        return this;
    }

    // 保存失败的回调,控制执行成功或失败的回调函数
    this.fail = function(){
        // 拿到参数(失败回调)
        var args = Array.prototype.slice.call(arguments)
        failArr = failArr.concat(args);
        return this;
    }

    // 控制成功失败状态
    this.Defered = function(){
        return new Defer();
    }
    var Defer = function(){
        // 状态值
        this.resolved = false;
        this.rejected = false
    }
    Defer.prototype = {
        resolve: function(){
            this.resolved = true;
            for(var i = 0; i < dfd.length; i++){
                // 有一个resolved不为true就不执行回调
                if(!dfd[i].resolved) return;
            }
            // 全部完成
            // 执行成功回调函数
            _exec(doneArr);
        },
        reject: function(){
            this.rejected = true
            // 失败回调
            _exec(failArr);
        }
    }
    // 遍历成功或者失败的回调,并调用
    function _exec(arr){
        for(var i = 0; i < arr.length; i++){
            arr[i] && arr[i]();
        }
    }
}

使用

var waiter = new Waiter()

// 异步函数1
var async1 = function(){
    var dfd = waiter.Defered()
    setTimeout(() => {
        console.log('async dome')
        dfd.resolve()
        // dfd.reject()
    }, 1000);
    return dfd;
}

// 异步函数2
var async2 = function(){
    var dfd = waiter.Defered()
    setTimeout(() => {
        console.log('async2 dome')
        dfd.resolve()
    }, 2000);
    return dfd;
}

waiter.when(async1(), async2()).done(function(){
    console.log('success')
}).fail(function(){
    console.log('fail');
})

结果

1602173306581.png

评论(0)


最新评论

  • https://www.studyglobus.com/author/carroll34a5552/

    Ценники на вывоз мусора сейчас космос, любые лайфхаки по экономии в тему.

  • Richardgrold

    1xbet onlayn kazino platforması ilə vaxtınızı daha səmərəli və maraqlı keçirin. Saytın canlı kazino bölməsi istifadəçilərə fərqli bir dünya təklif edir. Burada canlı dilerli kazino oyunlarının hər bir növünü sınaqdan keçirə bilərsiniz. Krupyelərin peşəkarlığı oyunun dinamikasını və marağını artırır. Müntəzəm olaraq yenilənən oyun siyahısı cansıxıcılığa yol vermir. Hesabınızı artırmaq üçün onlarla fərqli və etibarlı üsul mövcuddur. Qazanılan pullar cəmi bir neçə dəqiqə ərzində şəxsi hesabınıza köçürülür. Aktiv fəaliyyətinizə görə fərdi bonuslar və hədiyyələr qazana bilərsiniz. Dəstək xidməti həm çat, həm də e-poçt vasitəsilə kömək göstərir. 1xbet ailəsinə qoşulun və böyük uduşlar üçün ilk addımı atın. onlayn kazino

  • 砂岩白丘

    我一直梦想, 看到你们相册那样的地方。真棒。

  • 城市地標

    我喜欢, 这里分享真实经验。你的项目 就是 属于这里的。请继续。

  • 宗教地標

    我热爱这样的想法, 去那么多国家。真的很鼓舞。

  • 觀景高地

    能感受到热爱。继续保持 感受。

  • 最佳季節

    我关注这样的资源, 写得很实在。你的网站 就是 属于这里的。加油。

  • 1

    1

  • 1

    1

  • -1' OR 2+158-158-1=0+0+0+1 or 'TKCTZnRa'='

    1

日历

2026年07月

   1234
567891011
12131415161718
19202122232425
262728293031 

文章目录

推荐关键字: Linux webpack js 算法 MongoDB laravel JAVA jquery javase redis