Jquey Deferred 独立实现版本不依赖jquery

var eLingUtils = {
    GolbalFireActionCache: {},
    fireOnce: function (key, func) {
        if (GolbalFireActionCache.hasOwnProperty(key)) {
            return;
        } else {
            GolbalFireActionCache[key] = func();
        }
    },
    each: function (arr, func) {

        if (arr.length > 0) {
            for (var i = 0; i < arr.length; i++) {

                func.call(arr[i], i, arr[i])
            }
        }
    },
    extend: function (a, b) {
        var found = false;
        if (a == undefined) {
            found = true;
        } else {
            for (var c in a) {
                found = true;
                if (c in b) {
                    eLingUtils.extend(a[c], b[c]);
                }
            }
        }
        if (!found) {
            a = b;
        } else {
            if (b != undefined) {
                for (var d  in b) {
                    if (!(d in a)) {
                        a[d] = b[d];
                    }
                }
            }
        }
        return a;
    },
    Deferred: function (func) {
        var tuples = [
                ["resolve", "done", "resolved"],
                ["reject", "fail", "rejected"],
                ["notify", "progress"]
            ],
            state = "pending",
            callbacksProvider = {
                FireActionCache: {},
                addAndFireOnce: function (key, func) {
                    if (callbacksProvider.FireActionCache.hasOwnProperty(key)) {
                        return;
                    } else {
                        callbacksProvider.FireActionCache[key] = func();
                    }
                }, addCallbacks: function (key, func) {
                    if (callbacksProvider.FireActionCache.hasOwnProperty(key)) {

                        if (callbacksProvider.FireActionCache[key + "Initialized"] == false) {
                            var CachedParam = callbacksProvider.FireActionCache[key];
                            callbacksProvider.FireActionCache[key + "Initialized"] = true;
                            callbacksProvider.FireActionCache[key] = func;
                            for (var i = 0; i < CachedParam.length; i++) {
                                func.apply(CachedParam[i].contextCache, CachedParam[i].argumentsCache);
                            }
                        } else {
                            return;
                        }
                    } else {
                        callbacksProvider.FireActionCache[key + "Initialized"] = true;
                        callbacksProvider.FireActionCache[key] = func;
                    }
                }, memoryFire: function (key) {

                    if (callbacksProvider.FireActionCache.hasOwnProperty(key)) {
                        if (callbacksProvider.FireActionCache[key + "Initialized"]) {
                            return callbacksProvider.FireActionCache[key];
                        } else {
                            return function () {
                                callbacksProvider.FireActionCache[key].push({
                                    state: "pending",
                                    contextCache: this,
                                    argumentsCache: arguments

                                });
                            }
                        }

                    } else {
                        callbacksProvider.FireActionCache[key + "Initialized"] = false;
                        return function () {
                            callbacksProvider.FireActionCache[key] = [];
                            callbacksProvider.FireActionCache[key].push({
                                state: "pending",
                                contextCache: this,
                                argumentsCache: arguments

                            });
                        }
                    }
                }
            }, promise = {
                state: function () {
                    return state;
                }, always: function () {
                    deferred.done(arguments).fail(arguments);
                    return this;
                }, then: function () {
                    var fns = arguments;
                    return eLingUtils.Deferred(function (newDefer) {
                        eLingUtils.each(tuples, function (i, tuple) {
                            var action = tuple[0], fn = typeof(fns[i]) == "function" && fns[i];
                            deferred[tuple[1]](function () {
                                var returned = fn && fn.apply(this, arguments);
                                if (returned && typeof(returned.promise) == "function") {
                                    returned.promise()
                                        .done(newDefer.resolve)
                                        .fail(newDefer.reject)
                                        .progress(newDefer.notify);
                                } else {
                                    newDefer[action].apply(this === promise ? newDefer : this, arguments);
                                }
                            });
                        });
                        fns = null;
                    }).promise();
                }, promise: function () {
                    try {
                        return promise;
                    } catch (e) {

                    } finally {
                        if (func) {
                            func.call(deferred, deferred);
                        }
                    }
                }
            }, deferred = {};
        promise.pipe = promise.then;
        eLingUtils.each(tuples, function (i, tuple) {
            promise[tuple[1]] = function (func) {
                callbacksProvider.addCallbacks(tuple[0] + "With", func);
                return promise;
            };
            deferred[tuple[0]] = function () {
                if (tuple[0] == "notify") {
                    callbacksProvider.memoryFire(tuple[0] + "With").apply(this === deferred ? promise : this, arguments);
                    return this;
                } else {
                    callbacksProvider.addAndFireOnce(tuple[0] + "Fired", function () {

                        callbacksProvider.memoryFire(tuple[0] + "With").apply(this === deferred ? promise : this, arguments);
                        return this;
                    });
                }
            };
        });
        return eLingUtils.extend(deferred, promise);
    },
    when: function (subordinate) {
        var i = 0,
            resolveValues = Array.prototype.slice.call(arguments, 1),
            length = resolveValues.length,
            remaining = length !== 1 || ( subordinate && typeof(subordinate.promise) == "function" ) ? length : 0,
            deferred = remaining === 1 ? subordinate : eLingUtils.Deferred(),
            updateFunc = function (i, contexts, values) {
                return function (value) {
                    contexts[i] = this;
                    values[i] = arguments.length > 1 ? Array.prototype.slice.call(arguments) : value;
                    if (values === progressValues) {
                        deferred.notifyWith(contexts, values);
                    } else if (!( --remaining )) {
                        deferred.resolveWith(contexts, values);
                    }
                };
            }, progressValues, progressContexts, resolveContexts;
        if (length > 1) {
            progressValues = new Array(length);
            progressContexts = new Array(length);
            resolveContexts = new Array(length);
            for (; i < length; i++) {
                if (resolveValues[i] && typeof(resolveValues[i].promise) == "function") {
                    resolveValues[i].promise()
                        .done(updateFunc(i, resolveContexts, resolveValues))
                        .fail(deferred.reject)
                        .progress(updateFunc(i, progressContexts, progressValues));
                } else {
                    --remaining;
                }
            }
        }
        if (!remaining) {
            deferred.resolveWith(resolveContexts, resolveValues);
        }
        return deferred.promise();
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值