手写一个promise用法_动手写一个Promise

现在Promise用的比较频繁了,如果哪天突然不用了,可能逻辑就不好厘清了,回调没的说是一大把

废话不多说,进入正题

Promise这个东西很神奇,用起来舒服,若自己写一下,恐怕还真不简单,关键就一个字“绕”,绕过了也就好了

首先定义结构

class MyPromise {constructor(excutor) {}

then(onfulfilled,onrejected) {}

catch(onrejected) {}

}

以上也就是大体的结构了

结构清楚了,那么说如何设计呢,先看看Promise的示例

var p = new Promise((resolve,reject) => {

resolve(1)

})

p.then(console.log)

p.then(console.log)

以上的输出结果为

1

1

所以说内部应该有必要存这个结果值,同时还有必要存一系列的回调函数,所以先来看看构造函数的实现

广州包装设计公司http://www.maiqicn.com 电脑刺绣绣花厂 ttp://www.szhdn.com

构造函数

constructor(excutor) {

// 状态

this._state = 'pending'

// 成功回调

this._callbacks_resolved = []

// 失败回调

this._callbacks_rejected = []

// 执行

excutor((data) => {

// 避免重复执行

if (this._state !== 'pending') {

return

}

// 保存结果

this._data = data

// 状态变更

this._state = "resolved"

// 处理

this._handle()

},(err) => {

if (this._state !== 'pending') {

return

}

// 错误信息

this._err = err

// 状态变更

this._state = "rejected"

this._handle()

})

}

看看处理函数

也就是根据对应的状态执行对应的回调,当然不要忘了处理完之后要清空

_handle() {

if (this._state === 'pending') {

return;

}

// 为什么要延时,then的东西是不能马上执行的,可以看看micro-task和macro-task,这里只能模拟

setTimeout(() => {

if (this._state === 'resolved') {

this._callbacks_resolved.forEach(cb => cb(this._data))

} else {

this._callbacks_rejected.forEach(cb => cb(this._err))

}

this._callbacks_resolved = []

this._callbacks_rejected = []

})

}

then

到了关键的一步,也就是核心的then

这个then的放回结果本身就是一个Promise,所以是可以无限的套的,也就像这样.then().then()

还支持值传递,上一个没有处理的,直接流到下一级,上一级把错误处理后,下一级状态变更为resolved

最开始想直接返回this,发觉这样问题大了去了,所以得另外new一个MyPromise实例,代码如下

then(onfulfilled,onrejected) {

return new MyPromise((resolve,reject) => {

this._callbacks_resolved.push(data => {

// 没有处理,直接往后传

if (!onfulfilled) {

return resolve(data)

}

try {

let r = onfulfilled(data)

// 有then函数,就认为是Promise

if (r && typeof r.then === "function") {

return r.then(resolve,reject)

}

resolve(r)

} catch(e) {

// 有错误直接向后传

reject(e)

}

})

this._callbacks_rejected.push(err => {

if (!onrejected) {

return reject(err)

}

try {

let r = onrejected(err)

if (r && typeof r.then === "function") {

return r.then(resolve,reject)

}

resolve(r)

} catch(e) {

reject(e)

}

})

this._handle()

})

}

以上基本功能已经实现完成,最后还有一个catch函数,很简单,包装一下就好了

catch(onrejected) {

return this.then(undefined,onrejected)

}

随便写了个测试用例

var p = new MyPromise((resolve,reject) => {

resolve(1);

})

.then((n) => {

console.log(n);

return new MyPromise((resolve,reject) => {

resolve(2);

});

})

.then(console.log)

.then(() => {

throw new Error("error");

});

p.catch((e) => {

console.error(e);

});

p.catch((e) => {

console.error(e);

});

输出

1

2

error

error

完全符合预期

好了,完结

附上全部代码

class MyPromise {

constructor(excutor) {

// 状态

this._state = "pending";

// 成功回调

this._callbacks_resolved = [];

// 失败回调

this._callbacks_rejected = [];

// 执行

excutor(

(data) => {

// 避免重复执行

if (this._state !== "pending") {

return;

}

// 保存结果

this._data = data;

// 状态变更

this._state = "resolved";

// 处理

this._handle();

},(err) => {

if (this._state !== "pending") {

return;

}

// 错误信息

this._err = err;

// 状态变更

this._state = "rejected";

this._handle();

}

);

}

then(onfulfilled,reject) => {

this._callbacks_resolved.push((data) => {

// 没有处理,直接往后传

if (!onfulfilled) {

return resolve(data);

}

try {

let r = onfulfilled(data);

// 有then函数

if (r && typeof r.then === "function") {

return r.then(resolve,reject);

}

resolve(r);

} catch (e) {

// 有错误直接向后传

reject(e);

}

});

this._callbacks_rejected.push((err) => {

if (!onrejected) {

return reject(err);

}

try {

let r = onrejected(err);

if (r && typeof r.then === "function") {

return r.then(resolve,reject);

}

resolve(r);

} catch (e) {

reject(e);

}

});

this._handle()

});

}

catch(onrejected) {

return this.then(undefined,onrejected);

}

_handle() {

if (this._state === "pending") {

return;

}

// 为什么要延时,then的东西是不能马上执行的,可以看看micro-task和macro-task,这里只能模拟

setTimeout(() => {

if (this._state === "resolved") {

this._callbacks_resolved.forEach((cb) => cb(this._data));

} else {

this._callbacks_rejected.forEach((cb) => cb(this._err));

}

this._callbacks_resolved = [];

this._callbacks_rejected = [];

});

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值