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
        }
时间: 2024-12-10 23:40:38

Javascript Promise 学习 (中)的相关文章

Javascript Promise 学习

Promise 就是处理异步的一个规范方法 a();b();alert("a");如果a() 里面有一个ajax 或者settimeout 那么alert("a") 会先跑这就是异步了.从前我们用一堆callBack函数来解决问题,但是这样写不好看.promise 的写法美丽多了依据上面的例子a().then(b).then(function(){alert("");})这样它会先跑完 a -> b - > alert("&

JavaScript语言学习中的注意事项

javascript: 基于浏览器 基于对象 事件驱动 脚本语言 由: javascript: ECMAscript(ES) DOM文档对象模型 BOM浏览器对象模型,三部分组成 使用js的三种方式 1.HTML标签中内嵌js:<button ondblclick="javascript:alert('ssas')">点我呀!!!</button> 不建议使用 2.在HTML页面中直接使用: <script type="text/javascri

javascript Promise学习

目录 Promise 基础语法 三种状态 Promise原型方法 Promise.prototypr.then() Promise.prototype.catch() Promise.prototype.finally() Promise 的属性和方法 Promise.all(iterable) Promise.race(iterable) Promise.resolve(value) Promise.reject(err) Promise Promise 是ES6新增的对象,用来处理异步,使用

JavaScript学习中的挑战

当人们尝试学习 JavaScript , 或者其他编程技术的时候,常常会遇到同样的挑战: 有些概念容易混淆,特别是当你学习过其他语言的时候.很难找到学习的时间(有时候是动力).一旦当你理解了一些东西的时候,却很容易再一次忘记.可以使用的工具甚多且经常变化,所以不知道从哪里开始入手.幸运的是,这些挑战最终都可以被战胜.在这篇文章里,我将介绍 6 个思维技巧来帮你更快的学习 JavaScript ,让你成为一个更快乐更多产的程序员. 1.不要让将来的决定阻止你进步 对于很多学习 JavaScript

javascript学习中自己对作用域和作用域链理解

在javascript学习中作用域和作用域链还是相对难理解些,下面我关于javascript作用域和作用域链做一下详细介绍,给各位初学者答疑解惑. 首先我们介绍一下什么是作用域?  从字面上理解就是起作用的区域.   作用域主要有两种作用域:      1.块级作用域(js 不支持):主要用于C系列语言中,例如:Java Object-c/Swift(苹果开发语言).C++/C#.在此不做过多说明.      2.词法作用域  一个变量的作用范围,在代码写出来的那一刻就定下来了,不会根据代码的运

ES6中Promise学习笔记

参考资料: 廖雪峰 javascript教程-promise 阮一峰 ECMAScript 6 入门-Promise 对象 JavaScript Promise迷你书(中文版)

JavaScript在HTML中的使用--学习笔记

<script>元素 <script>属性: async:可选.表示应该立即下载脚本,但不应妨碍页面中的其他操作,比如下载其他资源或等待加载其他脚本.只对外部脚本文件有效. charset:可选.表示通过 src 属性指定的代码的字符集.由于大多数浏览器会忽略它的值,因此这个属性很少有用. defer:可选.表示脚本可以延迟到文档完全被解析和显示之后再执行.只对外部脚本文件有效. IE7 及更早版本对嵌入脚本也支持这个属性. language:已废弃.原来用于表示编写代码使用的脚本

【JavaScript】JavaScript Promise 探微

http://www.html-js.com/article/Promise-translation-JavaScript-Promise-devil-details 原文链接:JavaScript Promises … In Wicked Detail 我在 JavaScript 中使用 Promise 已经有一段时间了,目前我已经能高效的使用这一开始让我晕头转向的 东西.但真要细说起来,我发现还是不能完全理解它的实现原理,这也正是本文写作的目的所在.如果诸位读者也处在一知半解的状态,那请读完

如何在Promise链中共享变量?

译者按: 使用Promise写过异步代码的话,会发现在Promise链中共享变量是一个非常头疼的问题,这也是Async/Await胜过Promise的一点,我们在Async/Await替代Promise的6个理由有提过,这篇博客将有更详细的介绍. 原文: Passing data between Promise callbacks 译者: Fundebug 为了保证可读性,本文采用意译而非直译,并且对源代码进行了大量修改.另外,本文版权归原作者所有,翻译仅用于学习. 基于Promise编写异步代