资讯专栏INFORMATION COLUMN

自制简单的promise

tianlai / 2038人阅读

摘要:现在的已经是用的很广泛的,可以有效的解决地域回调的问题。那么现在我们可以制作一个简单的让自己更加熟悉。我们这样就知道了的运行机制了。

现在es6的promise已经是用的很广泛的,可以有效的解决地域回调的问题。
那么现在我们可以制作一个简单的promise,让自己更加熟悉promise。

一.回顾promise

先我们需要了解一下promise的用法。以下demo

var p=new Promise(function(resolve,reject){
    setTimeout(function(){
       resolve("success")
    },1000);
    console.log("创建一个新的promise");
})
p.then(function(x){
  console.log(x)
})

//输出:
创建一个新的promise
success

以上就是一个promise的实例。从上述例子可以看出,promise可以处理异步操作。此外还可以链式调用

二.了解一下promise规范https://promisesaplus.com/

我们主要关心它的要求有一下几点:

1.一个promise必须有3个状态,pending,fulfilled(resolved),rejected当处于pending状态的时候,可以转移到fulfilled(resolved)或者rejected状态。当处于fulfilled(resolved)状态或者rejected状态的时候,就不可变。
2.一个promise必须有一个then方法,then方法接受两个参数:
3.为了实现链式调用,then方法必须返回一个promise
三.制作promise

接下来我们来制作简单的promise,以下将分几个版本,来循序渐进的增加内容

1) v1.0版本
function myPromise(constructor){
    let self=this;
    self.status="pending" //定义状态改变前的初始状态
    self.value=undefined;//定义状态为resolved的时候的状态
    self.reason=undefined;//定义状态为rejected的时候的状态
    function resolve(value){
        //两个==="pending",保证了状态的改变是不可逆的
       if(self.status==="pending"){
          self.value=value;
          self.status="resolved";
       }
    }
    function reject(reason){
        //两个==="pending",保证了状态的改变是不可逆的
       if(self.status==="pending"){
          self.reason=reason;
          self.status="rejected";
       }
    }
    //捕获构造异常
    try{
       constructor(resolve,reject);
    }catch(e){
       reject(e);
    }
}

同时在原型链上增加then方法

myPromise.prototype.then=function(onFullfilled,onRejected){
   let self=this;
   switch(self.status){
      case "resolved":
        onFullfilled(self.value);
        break;
      case "rejected":
        onRejected(self.reason);
        break;
      default:       
   }
}

然后测试一下

var p=new myPromise(function(resolve,reject){resolve(1)});
p.then(function(x){console.log(x)})
//输出1

但是我们可以发现这边是没有异步过程的,即then里面是没有处理内容的

v1.1

增加异步功能

function myPromise(constructor){
    let self=this;
    self.status="pending" //定义状态改变前的初始状态
    self.value=undefined;//定义状态为resolved的时候的状态
    self.reason=undefined;//定义状态为rejected的时候的状态
    self.onFullfilledArray=[];
    self.onRejectedArray=[];
    function resolve(value){
       if(self.status==="pending"){
          self.value=value;
          self.status="resolved";
          self.onFullfilledArray.forEach(function(f){
                f(self.value);
                //如果状态从pending变为resolved,
                //那么就遍历执行里面的异步方法
          });
        
       }
    }
    function reject(reason){
       if(self.status==="pending"){
          self.reason=reason;
          self.status="rejected";
          self.onRejectedArray.forEach(function(f){
              f(self.reason);
             //如果状态从pending变为rejected, 
             //那么就遍历执行里面的异步方法
          })
       }
    }
    //捕获构造异常
    try{
       constructor(resolve,reject);
    }catch(e){
       reject(e);
    }
}
myPromise.prototype.then=function(onFullfilled,onRejected){
   let self=this;
   switch(self.status){
      case "pending":
        self.onFullfilledArray.push(function(){
             onFullfilled(self.value)
        });
        self.onRejectedArray.push(function(){
             onRejected(self.reason)
        });
        break;
      case "resolved":
        onFullfilled(self.value);
        break;
      case "rejected":
        onRejected(self.reason);
        break;
      default:       
   }
}

现在在来测试已经可以发出then了
但是现在还无法处理链式调用then

v1.3

增加then链式调用

v1.3.1

最简单的就是then返回一个对象,可以进行链式调用

myPromise.prototype.then=function(onFullfilled,onRejected){
   let self=this;
   switch(self.status){
      case "pending":
        self.onFullfilledArray.push(function(){
             onFullfilled(self.value)
        });
        self.onRejectedArray.push(function(){
             onRejected(self.reason)
        });
        break;
      case "resolved":
        onFullfilled(self.value);
        break;
      case "rejected":
        onRejected(self.reason);
        break;
      default:       
   }
   return this
}

一个简单的this就是promise对象本身,这样就可以了,按时this永远都是同一个promise对象,即then里的value永远都是相同的
因此我们需要返回一个新的promise

v1.3.2
promise.prototype.then = function(onFullfilled, onRejected) {

    var self = this
    let promise2

    switch (self.status) {
        case "pending":
            promise2 = new promise(function(resolve, reject) {
                self.onFullfilledArray.push(function() {
                    try {
                        let temple = onFullfilled(self.value)
                        resolve(temple)
                    } catch (e) {
                        reject(e)
                    }
                })
                self.onRejectedArray.push(function() {
                    try {
                        let temple = onRejected(self.reason);
                        resolve(temple)
                    } catch (e) {
                        reject(e) // error catch
                    }
                })
            })
            break;
        case "resolved":
            promise2 = new promise(function(resolve, reject) {
                try {
                    let temple = onFullfilled(self.value);
                    //将上次一then里面的方法传递进下一个Promise的状态
                    resolve(temple);
                } catch (e) {
                    reject(e); //error catch
                }
            })
            break;
        case "rejected":
            promise2 = new promise(function(resolve, reject) {
                try {
                    let temple = onRejected(self.reason);
                    //将then里面的方法传递到下一个Promise的状态里
                    resolve(temple);
                } catch (e) {
                    reject(e);
                }
            })
            break;
        default:
    }
    return promise2;
}

至此简单的promise已经完成了。但是这个promise还是有不少问题的,如then里面直接使用primise等。这些都是优化问题。
我们这样就知道了promise的运行机制了。

觉得不错的请点赞,谢谢。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/98750.html

相关文章

  • 从零开始写一个 Promise

    摘要:是什么在规范中,是一个类,它的构造函数接受一个函数。在这种情况下,是但处于状态。与一起使用关键字会暂停执行一个函数,直到等待的变成状态。此外,会一直等待调用直到下一个时序。 原文:Write Your Own Node.js Promise Library from Scratch作者:code_barbarian Promise 已经是 JavaScript 中异步处理的基石,回调...

    Binguner 评论0 收藏0
  • Java爬虫之利用Jsoup自制简单搜索引擎

    摘要:的官方网址为,其使用手册网址为本次分享将实现的功能为利用爬取某个搜索词语暂仅限英文的百度百科的介绍部分,具体的功能介绍可以参考博客爬虫自制简单的搜索引擎。   Jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。Jsoup的官方网址为: https:...

    GHOST_349178 评论0 收藏0
  • 自制简单range(Vue)

    摘要:废话不多说先上成果图实现思路主要分界面与逻辑两大块界面分为个部分左滑块长度左内容位置中间长度右滑块长度右内容位置逻辑个事件各滑块长度及位置计算选中时变色具体实现步骤首先我们明白整个容器的长度是不变的等于左边中间右边所以我们可以通过先获取总的 废话不多说先上成果图 showImg(https://segmentfault.com/img/remote/1460000016345728?w...

    sunnyxd 评论0 收藏0
  • 自制简单range(Vue)

    摘要:废话不多说先上成果图实现思路主要分界面与逻辑两大块界面分为个部分左滑块长度左内容位置中间长度右滑块长度右内容位置逻辑个事件各滑块长度及位置计算选中时变色具体实现步骤首先我们明白整个容器的长度是不变的等于左边中间右边所以我们可以通过先获取总的 废话不多说先上成果图 showImg(https://segmentfault.com/img/remote/1460000016345728?w...

    sewerganger 评论0 收藏0

发表评论

0条评论

tianlai

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<