• Javascript Promise 学习 (中)


    时隔多日,对promise有了多一点点的了解。

    最近用angularjs 做开发,所以研究了一下它的 $q 

    功能不算很强大,算是简化版的 Q.js

    参考了一下源码,不过我的等级还差很多...

    作为学习,我自己又重写了一篇。

    这次的比较整齐。代码也少了 .

            $q = function (asyncFn) {
                var defer = new Deferred();
                asyncFn(defer.resolve.bind(defer), defer.reject.bind(defer));
                return defer.promise;
            };
            $q.defer = function () {
                return new Deferred();
            };
            $q.reject = function (reason) {
                var defer = new Deferred();
                defer.reject(reason);
                return defer.promise;
            };
            $q.all = function (values) {            
                var defer = new Deferred();
                var finalDatas = [];
                var count = 0;
                values.forEach(function (value, i) {
                    count++;
                    $q.when(value, function (data) {
                        finalDatas[i] = data; //直接按index装入,不用另外排序
                        if (--count === 0) { //一个++ 一个-- 互相抵消
                            defer.resolve(finalDatas);
                        }
                    }, function (reason) {
                        defer.reject(reason);
                    });
                });
                return defer.promise;
            };
            $q.when = function (value, onFulfilled, onRejected, onNotify) {            
                if (value instanceof Promise) return value.then(onFulfilled, onRejected, onNotify);           
                var defer = new Deferred();
                defer.resolve(value);
                return defer.promise.then(onFulfilled, onRejected, onNotify);          
            };
    
            function Deferred() {
                this.promise = new Promise();
            }
            Deferred.prototype = {
                //resolve reject 几乎是一样的, notify 在调用后不会被删除
                resolve: function (data) {
                    var promise = this.promise;
                    //要延误执行,防止then方法还没有设置好回调,就想要resolve的情况
                    setTimeout(function () {                  
                        promise.states = "fulfilled";
                        promise._processCallback(data);
                    }, 0);
                },
                reject: function (reason) {
                    var promise = this.promise;
                    setTimeout(function () {                 
                        promise.states = "rejected";
                        promise._processCallback(reason);
                    }, 0);
                },
                notify: function (data) {
                    var promise = this.promise;
                    setTimeout(function () {                 
                        promise.states = "notify";
                        promise._processCallback(data, true);
                    }, 0);
                },
                constructor: Deferred
            }
            //主要是保存defer, 做promise连用
            function Callback(defer, onFulfilled, onRejected, onNotify) {
                this.defer = defer;
                this.onFulfilled = onFulfilled;
                this.onRejected = onRejected;
                this.onNotify = onNotify;
            }
            function Promise() {
                this.states = "pending";
                this.value = undefined;
                this.reason = undefined;
                this._callbacks = [];
            }
            Promise.prototype = {
                then: function (onFulfilled, onRejected, onNotify) {
                    //把回调收集起来,如果states不是等待就马上出发
                    var defer = new Deferred();
                    this._callbacks.push(new Callback(defer, onFulfilled, onRejected, onNotify));
                    if (this.states !== "pending") {
                        var data = (this.states === "fulfilled") ? this.value : this.reason;
                        this._processCallback(data);
                    }
                    return defer.promise;
                },
                "catch": function (onRejected) {
                    return this.then(null, onRejected);
                },
                'finally': function (cleanup) {                
                    return this.then(cleanup, cleanup);
                },
                _processCallback: function (data, is_keepCallback) {
                    //这里的data不接受promise,偷懒没做。哈哈
                    var promise = this;
                    if (this.states === "pending") return;             
                    var states = ("on-" + this.states).toCamelCase();
                    var promiseCallbacks = this._callbacks;
                    var length = promiseCallbacks.length;
                    for (var i = 0, l = promiseCallbacks.length; i < l; i++) {                  
                        var callback = (is_keepCallback) ?  promiseCallbacks[i] : promiseCallbacks.shift();
                        var defer = callback.defer;                   
                        if (G.isFunction(callback[states])) {
                            //要做错误处理哦
                            try {
                                //调用回调,
                                var returnValue = callback[states](data);
                                //如果是promise那就乾坤大挪移把promise连连接过去
                                if (returnValue instanceof Promise) {                              
                                    returnValue.then(defer.resolve.bind(defer), defer.reject.bind(defer));//这里要用bind,因为resolve内需要引用this
                                }
                                else {
                                    //不是的话就到值传给下一个promise咯
                                    defer.resolve(returnValue);
                                }                           
                            }
                            catch (e) {
                                defer.reject(e);
                            }
                        }
                        else {
                            //data不是函数就直接传下去
                            defer.resolve(data);
                        }
                    }
                },
                constructor: Promise
            }
  • 相关阅读:
    php文件
    简易版ajax
    localstory的储存与取出
    想了想,还是把之前的补齐,先放个封装的运动吧
    struts-032利用工具 PythonGUI
    Python GUI tkinter 学习笔记(三)
    Python GUI tkinter 学习笔记(二)
    Python GUI tkinter 学习笔记(一)
    先知xss挑战赛学习笔记
    Baiduyun
  • 原文地址:https://www.cnblogs.com/keatkeat/p/3947212.html
Copyright © 2020-2023  润新知