zoukankan      html  css  js  c++  java
  • JS底层挖掘

    //Promise版本的Ajax
    const getJSON = function(url) { const promise =new Promise(function(resolve, reject) { const handler = function() { if(this.readyState!==4) { return; } if(this.status===200) { resolve(this.responseText); } else { reject(new Error(this.statusText)); } }; const client = new XMLHttpRequest(); client.open("GET", url); client.onreadystatechange=handler; client.responseType="json"; client.setRequestHeader("Accept", "application/json"); client.send(); }); return promise; };
    getJSON("./demo.json").then(function(json) {
    console.log("Contents: "+ json);
    }).catch(function(err){
    console.log('出错了',err);
    });
    //Promise实现
    (function(window,undefined){
    
    // resolve 和 reject 最终都会调用该函数
    var final = function(status,value){
        var promise = this, fn, st;
            
        if(promise._status !== 'PENDING') return;
        
        // 所以的执行都是异步调用,保证then是先执行的
        setTimeout(function(){
            promise._status = status;
            st = promise._status === 'FULFILLED'
            queue = promise[st ? '_resolves' : '_rejects'];
    
            while(fn = queue.shift()) {
                value = fn.call(promise, value) || value;
            }
    
            promise[st ? '_value' : '_reason'] = value;
            promise['_resolves'] = promise['_rejects'] = undefined;
        });
    }
    
    //参数是一个函数,内部提供两个函数作为该函数的参数,分别是resolve 和 reject
    var Promise = function(resolver){
        if (!(typeof resolver === 'function' ))
            throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
        //如果不是promise实例,就new一个
        if(!(this instanceof Promise)) return new Promise(resolver);
    
        var promise = this;
        promise._value;
        promise._reason;
        promise._status = 'PENDING';
        //存储状态
        promise._resolves = [];
        promise._rejects = [];
        
        //
        var resolve = function(value) {
            //由于apply参数是arguments
            final.apply(promise,['FULFILLED'].concat([value]));
        }
    
        var reject = function(reason){
            final.apply(promise,['REJECTED'].concat([reason]));
        }
        
        resolver(resolve,reject);
    }
    
    Promise.prototype.then = function(onFulfilled,onRejected){
        var promise = this;
        // 每次返回一个promise,保证是可thenable的
        return new Promise(function(resolve,reject){
            
            function handle(value) {
                // 這一步很关键,只有這樣才可以將值傳遞給下一個resolve
                var ret = typeof onFulfilled === 'function' && onFulfilled(value) || value;
    
                //判断是不是promise 对象
                if (ret && typeof ret ['then'] == 'function') {
                    ret.then(function(value) {
                        resolve(value);
                    }, function(reason) {
                        reject(reason);
                    });
                } else {
                    resolve(ret);
                }
            }
    
            function errback(reason){
                reason = typeof onRejected === 'function' && onRejected(reason) || reason;
                reject(reason);
            }
    
            if(promise._status === 'PENDING'){
                promise._resolves.push(handle);
                promise._rejects.push(errback);
            }else if(promise._status === 'FULFILLED'){ // 状态改变后的then操作,立刻执行
                callback(promise._value);
            }else if(promise._status === 'REJECTED'){
                errback(promise._reason);
            }
        });
    }
    
    Promise.prototype.catch = function(onRejected){
        return this.then(undefined, onRejected)
    }
    
    Promise.prototype.delay = function(ms,value){
        return this.then(function(ori){
            return Promise.delay(ms,value || ori);
        })
    }
    
    Promise.delay = function(ms,value){
        return new Promise(function(resolve,reject){
            setTimeout(function(){
                resolve(value);
                console.log('1');
            },ms);
        })
    }
    
    Promise.resolve = function(arg){
        return new Promise(function(resolve,reject){
            resolve(arg);
        })
    }
    
    Promise.reject = function(arg){
        return Promise(function(resolve,reject){
            reject(arg);
        })
    }
    
    Promise.all = function(promises){
        if (!Array.isArray(promises)) {
            throw new TypeError('You must pass an array to all.');
        }
        return Promise(function(resolve,reject){
            var i = 0,
                result = [],
                len = promises.length,
                count = len
                
            //这里与race中的函数相比,多了一层嵌套,要传入index
            function resolver(index) {
              return function(value) {
                resolveAll(index, value);
              };
            }
    
            function rejecter(reason){
                reject(reason);
            }
    
            function resolveAll(index,value){
                result[index] = value;
                if( --count == 0){
                    resolve(result)
                }
            }
    
            for (; i < len; i++) {
                promises[i].then(resolver(i),rejecter);
            }
        });
    }
    
    Promise.race = function(promises){
        if (!Array.isArray(promises)) {
            throw new TypeError('You must pass an array to race.');
        }
        return Promise(function(resolve,reject){
            var i = 0,
                len = promises.length;
    
            function resolver(value) {
                resolve(value);
            }
    
            function rejecter(reason){
                reject(reason);
            }
    
            for (; i < len; i++) {
                promises[i].then(resolver,rejecter);
            }
        });
    }
    
    window.Promise = Promise;
    
    })(window);
  • 相关阅读:
    Chrome快捷键统计
    数据封装
    数据抽象
    linux c++ 服务器端开发面试必看书籍(转载)
    闭包和高阶函数
    this,call,apply,bind
    DOM浏览器window对象模型
    jquery滚动条
    xml教程
    多态
  • 原文地址:https://www.cnblogs.com/princess-knight/p/9325957.html
Copyright © 2011-2022 走看看