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

JS面向对象

在JS中一切皆对象,但JS并不是一种真正的面向对象(OOP)的语言,因为它缺少类(class)的概念。虽然ES6引入了class和extends,使我们能够轻易地实现类和继承。但JS并不存在真实的类,JS的类是通过函数以及原型链机制模拟的,本小节的就来探究如何在ES5环境下利用函数和原型链实现JS面向对象的特性

在开始之前,我们先回顾一下原型链的知识,后续new和继承等实现都是基于原型链机制。很多介绍原型链的资料都能写上洋洋洒洒几千字,但我觉得读者们不需要把原型链想太复杂,容易把自己绕进去,其实在我看来,原型链的核心只需要记住三点:

每个对象都有__proto__属性,该属性指向其原型对象,在调用实例的方法和属性时,如果在实例对象上找不到,就会往原型对象上找

构造函数的prototype属性也指向实例的原型对象

原型对象的constructor属性指向构造函数

模拟实现new

首先我们要知道new做了什么

创建一个新对象,并继承其构造函数的prototype,这一步是为了继承构造函数原型上的属性和方法

执行构造函数,方法内的this被指定为该新实例,这一步是为了执行构造函数内的赋值操作

返回新实例(规范规定,如果构造方法返回了一个对象,那么返回该对象,否则返回第一步创建的新对象)

// new是关键字,这里我们用函数来模拟,new Foo(args) <=> myNew(Foo, args)

function myNew(foo, ...args) {

// 创建新对象,并继承构造方法的prototype属性, 这一步是为了把obj挂原型链上, 相当于obj.__proto__ = Foo.prototype

let obj = Object.create(foo.prototype)

// 执行构造方法, 并为其绑定新this, 这一步是为了让构造方法能进行this.name = name之类的操作, args是构造方法的入参, 因为这里用myNew模拟, 所以入参从myNew传入

let result = foo.apply(obj, args)

// 如果构造方法已经return了一个对象, 那么就返回该对象, 一般情况下,构造方法不会返回新实例,但使用者可以选择返回新实例来覆盖new创建的对象 否则返回myNew创建的新对象

return typeof result === 'object' && result !== null ? result : obj

}

function Foo(name) {

this.name = name

}

const newObj = myNew(Foo, 'zhangsan')

console.log(newObj) // Foo {name: "zhangsan"}

console.log(newObj instanceof Foo) // true

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Promise是一种异步编程的解决方案,可以避免回调地狱的问题。下面是使用class手写一个Promise的示例代码: ``` class MyPromise { constructor(executor) { this.status = 'pending'; // Promise的状态 this.value = undefined; // Promise的结果 this.reason = undefined; // Promise的错误信息 const resolve = (value) => { if (this.status === 'pending') { this.status = 'fulfilled'; this.value = value; } }; const reject = (reason) => { if (this.status === 'pending') { this.status = 'rejected'; this.reason = reason; } }; try { executor(resolve, reject); } catch (error) { reject(error); } } then(onFulfilled, onRejected) { onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (value) => value; onRejected = typeof onRejected === 'function' ? onRejected : (reason) => { throw reason }; const promise2 = new MyPromise((resolve, reject) => { if (this.status === 'fulfilled') { setTimeout(() => { try { const x = onFulfilled(this.value); resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, ); } else if (this.status === 'rejected') { setTimeout(() => { try { const x = onRejected(this.reason); resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, ); } else { this.onFulfilledCallbacks.push(() => { setTimeout(() => { try { const x = onFulfilled(this.value); resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, ); }); this.onRejectedCallbacks.push(() => { setTimeout(() => { try { const x = onRejected(this.reason); resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, ); }); } }); return promise2; } catch(onRejected) { return this.then(null, onRejected); } } function resolvePromise(promise2, x, resolve, reject) { if (promise2 === x) { reject(new TypeError('Chaining cycle detected for promise')); } let called = false; if (x !== null && (typeof x === 'object' || typeof x === 'function')) { try { const then = x.then; if (typeof then === 'function') { then.call(x, (y) => { if (called) return; called = true; resolvePromise(promise2, y, resolve, reject); }, (r) => { if (called) return; called = true; reject(r); }); } else { resolve(x); } } catch (error) { if (called) return; called = true; reject(error); } } else { resolve(x); } } ``` 以上是一个简单的Promise实现,其中包含了Promise的基本功能,如状态管理、then方法、catch方法等。需要注意的是,Promise的实现并不是一件简单的事情,需要考虑到各种边界情况,才能保证其正确性和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值