如何用Javascript自己实现Promise

在Javascript中做异步处理时,我们通常都要用到Promise。各大Javascript库中都有Promise的实现,例如JQuery和Dojo等。Javascript也有标准的Promise的定义,不过不幸的是IE不支持标准的Promise。下面是对标准Promise的说明文档:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

在有些情况下,如果我们不愿用到已有的Javascript库,又想使用Promise来做异步处理,那就需要自己实现一个Promise,特别是在IE上需要。另外,很多面试都会问到这样的问题,如何自己实现一个Promise。下面我做了一个简单的实现,代码很简单,但是基本功能已经具备了,稍作完善就可以在产品中用了。

// Promise的构造函数,传入的参数executor实际上是一个函数,executor的参数有两个一个是resolve函数,一个是reject函数

function Promise(executor) {    

    if(executor && typeof(executor)=='function' ) { // 判断executor是否是函数

        executor(this.resolver.bind(this),this.reject.bind(this)); //立即调用executor,传入的参数是自己的resolver函数,这里需要用bind(this),这样才能保证调用resolver时用Promise自己的执行环境

    }

}
Promise.prototype.then = function(onFulfilled) {  // then的参数是一个函数,当我们调用完resolve之后调用这个函数

    this.onFulfilled = onFulfilled; //我们需要先保存这个函数,以备以后调用

    return new Promise(function(resolver,rejector){ // 这里我们需要返回一个新的Promise,这样才能实现链式调用

        this.nextResolver = resolver; // 保存resolver以便下次调用

    }.bind(this));

}
Promise.prototype.resolver = function(returnValue) {

    if(this.onFulfilled && typeof(this.onFulfilled) == 'function') {

        let newReturnValue = this.onFulfilled(returnValue); // 调用then传入的函数

        if(this.nextResolver) {

            this.nextResolver(newReturnValue); //如果有链式调用,继续调用下一个resolve

        }

    }

}
Promise.prototype.reject = function(error) {

    if(this.onRejected && typeof(this.onRejected) == 'function') {

        this.onRejected(error);

    }

}

我们再通过以下的使用来验证我们实现的Promise。

let myFirstPromise = new Promise((resolve, reject) => {

  // We call resolve(...) when what we were doing asynchronously was successful, and reject(...) when it failed.

  // In this example, we use setTimeout(...) to simulate async code.

  // In reality, you will probably be using something like XHR or an HTML5 API.

  setTimeout(function(){

    resolve("Success!"); // Yay! Everything went well!

  }, 250);

});

myFirstPromise.then((successMessage) => {

  // successMessage is whatever we passed in the resolve(...) function above.

  // It doesn't have to be a string, but if it is only a succeed message, it probably will be.

  console.log("Yay! " + successMessage);

  return "Success 2";

}).then((successMessage) => {

  // successMessage is whatever we passed in the resolve(...) function above.

  // It doesn't have to be a string, but if it is only a succeed message, it probably will be.

  console.log("Yay2! " + successMessage);

}).then((successMessage) => {

  // successMessage is whatever we passed in the resolve(...) function above.

  // It doesn't have to be a string, but if it is only a succeed message, it probably will be.

  console.log("Yay3! " + successMessage);

});

你可能感兴趣的:(如何用Javascript自己实现Promise)