jQuery之Deferred解读

来源:互联网 发布:淘宝双十一2017规则 编辑:程序博客网 时间:2024/05/02 07:17

针对用的比较多的Deferred进行解读,所有注解都在代码行中

(function (jQuery) {    var sliceDeferred = [].slice;    jQuery.extend({        Deferred: function (func) {            var doneList = jQuery.Callbacks("once memory"),//成功回调函数列表                failList = jQuery.Callbacks("once memory"),//失败回调函数列表                progressList = jQuery.Callbacks("memory"),//消息过程回调函数列表                state = "pending",//初始状态 还有 resolved、rejected                lists = {                    resolve: doneList,                    reject: failList,                    notify: progressList                },                //异步队列的只读副本                promise = {                    done: doneList.add, //添加到成功回调函数列表的方法                    fail: failList.add, //添加到失败回调函数列表的方法                    progress: progressList.add,//添加到消息过程回调函数的列表方法                    state: function () {                        return state;                    },                    isResolved:doneList.fired,//成功回调函数列表是否被执行                    isRejected: failList.fired,//失败回调函数列表是否被执行                    then: function (doneCallbacks, failCallbacks, progressCallbacks) {//快速添加到成功、失败、消息回调函数列表方法                        deferred.done(doneCallbacks).fail(failCallbacks).progress(progressCallbacks);                        return this;                    },                    always: function () {                         deferred.done.apply(deferred, arguments).fail.apply(deferred, arguments);                        return this;                    },                    //工具方法,过滤当前异步队列的状态和参数,并且返回一个新的异步队列副本                    //处理ajax中嵌套ajax ,这个简称过滤器                    pipe: function (fnDone, fnFail, fnProgress) {                        return jQuery.Deferred(function (newDefer) {                            jQuery.each({                                done: [fnDone, "resolve"],                                fail: [fnFail, "reject"],                                progress:[fnProgress,"notify"]                            }, function (handler,data) {                                var fn = data[0],                                    action = data[1],                                    returned;                                if (jQuery.isFunction(fn)) {                                    deferred[handler](function () {                                        returned = fn.apply(this, arguments);                                        if (returned && jQuery.isFunction(returned.promise)) {                                            returned.promise().then(newDefer.resolve, newDefer.reject, newDefer.notify);                                        } else {                                            newDefer[action + "With"](this === deferred ? newDefer : this, [returned]);                                        }                                    });                                } else {                                    deferred[handler](newDefer[action]);                                }                            });                        }).promise();                    },                    promise: function (obj) {                        if (obj == null) {                            obj = promise;                        } else {                            for (var key in promise) {                                obj[key] = promise[key];                            }                        }                        return obj;                    }                },                //把只读副本promise中的方法添加到异步队列deferred中                deferred = promise.promise({}),//异步队列                key;            //添加触发成功、失败、消息过程回调函数列表的方法            for (key in lists) {                //deferred.resolve=doneList.fire                //deferred.reject=failList.fire                //deferred.notify=progressList.fire                deferred[key] = lists[key].fire;                //deferred.resolveWith=doneList.fireWith                //deferred.rejectWith=failList.fireWith                //deferred.notifyWith=progressList.fireWith                deferred[key + "With"] = lists[key].fireWith;            }            //分别在deferred中追加三个成功回调函数、三个失败函数            deferred.done(function () {                state = "resolved";            }, failList.disable, progressList.lock).fail(function () {                state = "rejected";            }, doneList.disable, progressList.lock);            //如果传递了函数类型的参数,就执行            if (func) {                //如果传入的参数为function,调用参数函数时,指定上下文对象为deferred,参数为deferred                //这样传入的函数可以调用deferred的方法                func.call(deferred, deferred);            }            //全部处理完成            return deferred;        },        //Deferred帮助类 jQuery.when(deferreds)        when: function (firstParam) {            //arguments 其实是一个对象,有点类似数组,这里通过[].slice.call(arguments,0)转换为数组            //但是如果是真实的object={name:'',age:30}这种,[].slice.call(object,0)是行不通的            var args = sliceDeferred.call(arguments, 0),                 i = 0,                length = args.length,                pValues = new Array(length),                count = length,                pCount = length,                deferred = length <= 1 && firstParam && jQuery.isFunction(firstParam.promise) ? firstParam : jQuery.Deferred(),                promise = deferred.promise();            function resolveFunc(i){                return function (value) {                    args[i] = arguments.length > 1 ? sliceDeferred.call(arguments, 0) : value;                    if (!(--count)) {                        deferred.resolveWith(deferred, args);                    }                };            }            function progressFunc(i) {                return function (value) {                    pValues[i] = arguments.length > 1 ? sliceDeferred.call(arguments, 0) : value;                    deferred.notifyWith(promise, pValues);                };            }            if (length > 1) {                for (; i < length; i++) {                    if (args[i] && args[i].promise && jQuery.isFunction(args[i].promise)) {                        args[i].promise().then(resolveFunc(i), deferred.reject, progressFunc(i));                    } else {                        --count;                    }                }                if (!count) {                    deferred.resolveWith(deferred, args);                }            } else if (deferred !== firstParam) {                deferred.resolveWith(deferred, length ? [firstParam] : []);            }            return promise;        }    });})(jQuery)//对Pipe使用的讲解//Demo--01var defer = $.Deferred(),    filtered = defer.pipe(function (value) {        return value * 2;    });defer.resolve(5);filtered.done(function (value) {    alert("Value is ( 2*5 = ) 10: " + value);});//Demo--02var defer = $.Deferred(),    filtered = defer.pipe(null, function (value) {        return value * 3;    });defer.reject(6);filtered.fail(function (value) {    alert("Value is ( 3*6 = ) 18: " + value);});//Demo--03var request = $.ajax(url, { dataType: "json" }),    chained = request.pipe(function (data) {        return $.ajax(url2, { data: { user: data.userId } });    });chained.done(function (data) {    //url2返回后的数据});//对When的使用方法//Demo--01var d1 = $.Deferred();var d2 = $.Deferred();var d3 = $.Deferred();$.when(d1, d2, d3).done(function (v1, v2, v3) {    console.log(v1); // v1 is undefined    console.log(v2); // v2 is "abc"    console.log(v3); // v3 is an array [ 1, 2, 3, 4, 5 ]});//Demo--02$.when($.ajax("/page1"), $.ajax("/page2")).done(function (a1, a2) {    /* a1 and a2 are arguments resolved for the        page1 and page2 ajax requests, respectively */    var jqXHR = a1[2]; /* arguments are [ "success", statusText, jqXHR ] */    if (/Whip It/.test(jqXHR.responseText)) {        console.log("第一个页面的数据");    }});//Demo--03 then为快捷的done、fail、progress$.when($.ajax("test.aspx")).then(function (data, textStatus, jqXHR) {    alert(jqXHR.status); });
0 0
原创粉丝点击