乐趣区

关于javascript:面试题promise的链式怎么实现的

前言

之前有过一次面试,面试官问 promise 相干的知识点,而后我答复了,他诘问说 promise 的链式怎么实现?我过后没反馈过去。面试官很有急躁,说 jquery 也是有链式的,你看过 jquery 的源码吗?它的链式怎么写的?我还是不晓得,起初没通过面试,这个知识点常被我回顾,当初正好有工夫,来写一写

注释

答案是:返回 this

先来一个例子:

var person = {
    name: 'johan',
    age: 28,
    sayName: function() {console.log('my name is' + this.name)
    },
    sayAge: function() {console.log('my age is' + this.age)
    }
}

命名一个对象,它有两个办法,sayName 和 sayAge,如果我想这样示意 person.sayName().sayAge() 呢?怎么做,在办法 sayName 和 sayAge 中返回 this,即

var person = {
    name: 'johan',
    age: 28,
    sayName: function() {console.log('my name is' + this.name)
        return this;
    },
    sayAge: function() {console.log('my age is' + this.age)
        return this;
    }
}

这就是示意,调用办法 sayName、sayAge 后,返回调用者,即例子 person.sayName(),person 调用 sayName,调用完后返回值还是 person。所以它能够持续链式调用 sayAge,因为它示意的还是 person

Promise 中的链式

Promise 自身没有链式,然而 Promise 的实例对象中的 then 有链式

function MyPromise(executor) { }

MyPromise.prototype.then = function (onFulfilled, onRejected) {return new Promise((resolve, reject) => {...})
}

当你应用 Promise 时,个别是这样应用:

let promise = new Promise((resolve, reject) => {setTimeout(resolve, 1000)
})
promise.then(() => {console.log('1s 后显示')
})

如果加上链式

promise.then(() => {console.log('1s 后显示, 第一个')
}).then(() => {console.log('1s 后显示,第二个')
})

所以很显著,每调用一次 then,就是返回一个实例对象(return new Promise

Jquery 中的链式

源码太多内容,就拿 core.js 中的代码为例子

jQuery.fn = jQuery.prototype = {

    // The current version of jQuery being used
    jquery: version,

    constructor: jQuery,

    // The default length of a jQuery object is 0
    length: 0,

    toArray: function() {return slice.call( this);
    },

    // Get the Nth element in the matched element set OR
    // Get the whole matched element set as a clean array
    get: function(num) {

        // Return all the elements in a clean array
        if (num == null) {return slice.call( this);
        }

        // Return just the one element from the set
        return num < 0 ? this[num + this.length] : this[num];
    },

    // Take an array of elements and push it onto the stack
    // (returning the new matched element set)
    pushStack: function(elems) {

        // Build a new jQuery matched element set
        var ret = jQuery.merge(this.constructor(), elems );

        // Add the old object onto the stack (as a reference)
        ret.prevObject = this;

        // Return the newly-formed element set
        return ret;
    },

    // Execute a callback for every element in the matched set.
    each: function(callback) {return jQuery.each( this, callback);
    },

    map: function(callback) {return this.pushStack( jQuery.map( this, function( elem, i) {return callback.call( elem, i, elem);
        } ) );
    },

    slice: function() {return this.pushStack( slice.apply( this, arguments) );
    },

    first: function() {return this.eq( 0);
    },

    last: function() {return this.eq( -1);
    },

    even: function() {return this.pushStack( jQuery.grep( this, function( _elem, i) {return ( i + 1) % 2;
        } ) );
    },

    odd: function() {return this.pushStack( jQuery.grep( this, function( _elem, i) {return i % 2;} ) );
    },

    eq: function(i) {
        var len = this.length,
            j = +i + (i < 0 ? len : 0);
        return this.pushStack(j >= 0 && j < len ? [ this[ j] ] : []);
    },

    end: function() {return this.prevObject || this.constructor();
    }
};

咱们不必看全副,但看其中的办法,是不是和最开始的例子很像——return this

所以链式不可怕,可怕的是,动都不动就自我劝退

本文参加了 SegmentFault 思否征文「如何“反杀”面试官?」,欢送正在浏览的你也退出。

退出移动版