记一次手写Promise

记第一次手写Promise

之前做项目的时候,一般使用AJAX请求数据,相信大多数同学都会使用.then来处理一些异步任务,但是这样的话可能会发生回调地狱,脑子混乱… 直到有一天,我看到了这段代码

function asyncFn1() {
  console.log('asyncFn1 run');
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      resolve('asyncFn1执行完了');
    }, 2000)
  })
}

function asyncFn2() {
  console.log('asyncFn2 run');
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      resolve('asyncFn2执行完了');
    }, 1000)
  })
}

function normalFn3() {
  console.log('normalFn3 run');
}

// 这样就比较好理解了,当asyncFn1re的resolve()执行的时候,才会执行.then()里面的函数,同理
asyncFn1().then(asyncFn2).then(normalFn3);

(可能是为了更好的链式使用.then,所以一般都使用函数返回一个Promise,而不是直接声明Promise???)

不管怎么说,我们今天就是要手写一个Promise,准备好了吗?

我们首先来看Promise的正常使用方法
// Promise在创建的时候,接收一个函数对象(被称为excutor),这个函数有两个参数
let p = new Promise((resolve, reject) => {
  console.log('这个函数是立即执行的');
  setTimeout(() => {
    resolve('异步操作得到的数据') // 可以把这里换成reject(’失败‘)试试	
  }, 1)    
})

// Promise的实例还有一个then方法,也接收两个参数,第一个参数为’成功时的回调‘,第二个参数为’失败时的回调‘
p.then((data) => {
    console.log('success:',data);
}, (data) => {
    console.log('eorr:',data);
})

当resolve()方法被执行的时候,就会执行then中的第一个函数,当reject()方法被执行的时候,就会执行then中的第二个函数

现在,我们尝试着自己实现一个Promise,暂且称为MyPromise
// 还是使用ES5的语法来写
// 刚刚上文中提到,我们在new Promise的时候,传入一个function对象,称之为excutor
function MyPromise(excutor) {
    var self = this;
    self.resolve = '';
    self.reject = '';
    self.value = '';
    self.reason = '';
    self.onResolvedCallbacks = [];
    self.onRejectedCallbacks = [];
    // 3.这里有一个隐藏的知识点,new Promise创建的实例有一个默认的状态 --- ‘pending’,只有在resovle或者reject的时候才会改变这个状态,且改变之后不能创新修改
    function resolve(value1) {
        if (self.status === 'pending') {
            self.status = 'resolved';
            self.value = value1;
            self.onResolvedCallbacks.forEach((callback) => {
                callback()
            })
        }
    }
    
    function reject(value2) {
        if (self.status === 'pending') {
            self.status = 'rejected';
            self.reason = value2;
            self.onRejectedCallbacks.forEach((callback) => {
                callback()
            })
        }
    }
    excutor(resolve, reject); // 1.传进来的这个excutor是立即执行的
}
// 2.刚刚上文中明显可以看到,Promise的实例p,有一个then方法,且接收两个参数,分别是'成功回调','失败回调'
MyPromise.prototype.then = (resolve, reject) => {
    let self = this;
    if (self.status === 'resovled')
        // 4. 我们会更具Promise的状态值去决定调用then中的第一个,还是第二个函数,并且赋值 
        resolve(self.value1);
    }
    if (self.status === 'rejected') {
        reject(self.value2);
    }
	// 5.执行的时候,发现,有两个问题 1.异步调用顺序不正确 2.多次使用.then(不是链式)的时候会有问题
	// 所以,我们肯定在将多次的then里面要做的事情,在'pending'状态下,先放在数据中先存储起来,等'resolve'的时候,再调用
 	if (self.status === 'pending') {
        self.onResolvedCallbacks.push(() => resolve(self.value));
        self.onRejectedCallbacks.push(() => resolve(self.reason));
    }
}

写到这里,应该足够理解Promise的原理了,但是现在还是是存在一些问题的,比如,Promise的链式调用,我们目前还没有实现的,就是文章首页的那种写法,但是个人不是很喜欢这样的写法,之后在开发中可能会多尝试一下 async await的开发方式(听说很香,也很容易从字面上理解)

function asyncFn1(){
    console.log('asyncFn1');
    return new Promise(function(resolve){
        setTimeout(function(){
            resolve('123');
        }, 2000)
    })
}

function asyncFn2() {
    console.log('asyncFn2');
    return new Promise(function(resolve){
        setTimeout(function(){
            resolve('456');
        }, 2000)
    })
}

async function asyncFn () {
    var a = await asyncFn1();
    var b = await asyncFn2();

    console.log(a,b)
}

asyncFn();

详情可以参考:https://www.jianshu.com/p/b4fd76c61dc9

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
信息数据从传统到当代,是一直在变革当中,突如其来的互联网让传统的信息管理看到了革命性的曙光,因为传统信息管理从时效性,还是安全性,还是可操作性等各个方面来讲,遇到了互联网时代才发现能补上自古以来的短板,有效的提升管理的效率和业务水平。传统的管理模式,时间越久管理的内容越多,也需要更多的人来对数据进行整理,并且数据的汇总查询方面效率也是极其的低下,并且数据安全方面永远不会保证安全性能。结合数据内容管理的种种缺点,在互联网时代都可以得到有效的补充。结合先进的互联网技术,开发符合需求的软件,让数据内容管理不管是从录入的及时性,查看的及时性还是汇总分析的及时性,都能让正确率达到最高,管理更加的科学和便捷。本次开发的医院后台管理系统实现了病房管理、病例管理、处方管理、字典管理、公告信息管理、患者管理、药品管理、医生管理、预约医生管理、住院管理、管理员管理等功能。系统用到了关系型数据库中王者MySql作为系统的数据库,有效的对数据进行安全的存储,有效的备份,对数据可靠性方面得到了保证。并且程序也具备程序需求的所有功能,使得操作性还是安全性都大大提高,让医院后台管理系统更能从理念走到现实,确确实实的让人们提升信息处理效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值