小伙伴们你们好,这里我将带你们手写Promise,做为前端的开发者,在平常的工做中,确定避免不了一个问题,那就是异步编程前端
今天就来为你们重要讲解一下promise,完全的弄懂它node
在学习以前咱们须要弄懂如下的:git
参考文档:https://promisesaplus.com/
指一个 promise 成功时进行的一系列操做,如状态的改变、回调的执行。虽然规范中用 fulfill 来表示解决,但在后世的 promise 实现多以 resolve 来指代之es6
指一个 promise失败时进行的一系列操做github
所谓终值,指的是 promise 被解决时传递给解决回调的值,因为 promise 有一次性的特征,所以当这个值被传递时,标志着 promise 等待态的结束,故称之终值,有时也直接简称为值(value)npm
也就是拒绝缘由,指在 promise 被拒绝时传递给拒绝回调的值编程
promise是一个拥有then方法的对象或函数,其行为符合本规范数组
是一个定义了then方法的对象或函数promise
指任何JavaScript的合法值(包括undefined、thenable和promise)服务器
是适用throw语句抛出的一个值
在须要多个操做的时候,会致使多个回调函数嵌套,致使代码不够直观,就是常说的回调地狱
若是几个异步操做之间并无先后顺序之分,但须要等多个异步操做都完成后才能执行后续的任务,没法实现并行节约时间
Promise本意是承诺,在程序中的意思就是承诺我过一段时间后会给你一个结果:
何时会用到过一段时间?
是异步操做
异步是指可能比较长时间才有结果的才作,例如网络请求、读取本地文件等
一个Promise的当前状态必须为如下三种状态中的一种
处于等待态时,promise需知足如下条件:
能够迁移至执行态或拒绝态
处于执行态时,promise 需知足如下条件:
不能迁移至其余任何状态
必须拥有一个不可变的终值
处于拒绝态时,promise须要知足如下条件
不能迁移至其余任何状态
必须拥有一个不可变的据因
一个promise必须提供一个then方法以访问其当前值、终值和据因
promise的then方法接受两个参数:
promise.then(onFulfilled, onRejected)
onFulfilled 和 onRejected 都是可选参数
若是onFulfilled是函数:
若是onRejected是函数:
onFulfilled 和 onRejected 只有在执行环境堆栈仅包含平台代码时才可被调用
onFulfilled 和 onRejected 必须被做为函数调用(即没有 this 值)
then 方法能够被同一个promise调用屡次
then 方法必须返回一个 promise 对象
在开始以前咱们须要建立三个文件
代码以下:
<font face="楷体">index.js</font>
new Promise((resolve, reject) => { setTimeout(() => { resolve(1) }) }).then(value => { console.log('value',value) },reason => { console.log('reason',reason) })
<font face="楷体">运行结果:</font>
value 1
代码以下:
<font face="楷体">index.js</font>
new Promise(1)
<font face="楷体">promise.js</font>
class Promise { constructor(executor){ //参数效验 if(typeof executor !== 'function'){ throw new TypeError('Promise resolver ${executor} is not a function') } } }
<font face="楷体">运行结果:</font>
Promise resolver 1 is not a function
代码以下
<font face="楷体">index.js</font>
new Promise((resolve, reject) => { console.log('早上好!') resolve(1) })
<font face="楷体">promise.js</font>
class Promise { constructor(executor){ //参数效验 if(typeof executor !== 'function'){ throw new TypeError('Promise resolver ${executor} is not a function') } const resolve = function (){ } const reject = function (){ } executor(resolve,reject) } }
<font face="楷体">运行结果:</font>
早上好!
代码以下:
<font face="楷体">promise.js</font>
class Promise { constructor(executor){ //不能相信用户的输入,因此这里要作参数效验 if(typeof executor !== 'function'){ throw new TypeError('Promise resolver ${executor} is not a function') } //记录状态和值的改变 //初始化值 this.value = null //终值 this.reason = null //拒因 this.state = 'pending' //状态 const resolve = value => { //成功后的一系列操做(状态的改变,成功回调的执行) if(this.state === 'pending'){ //状态进行改变 this.state = 'fulfilled' //执行成功的回调,把终值进行赋值 this.value = value } } const reject = reason =>{ //失败后的一系列操做(状态的改变,失败回调的执行) if(this.state === 'pending'){ //状态进行改变 this.state = 'rejected' //执行成功的回调,把据因进行赋值 this.reason = reason } } executor(resolve,reject) } } module.exports = Promise
<font face="楷体">test.js</font>
const Promise = require('./promise.js') new Promise((resolve, reject) => { console.log('早上好!') resolve(1) })
<font face="楷体">运行结果:</font>
早上好!
优化后的代码以下
<font face="楷体">promise.js</font>
class Promise { constructor(executor){ //不能相信用户的输入,因此这里要作参数效验 if(typeof executor !== 'function'){ throw new TypeError('Promise resolver ${executor} is not a function') } this.initValue() this.initBind() executor(this.resolve,this.reject) } //绑定 this initBind(){ this.resolve = this.resolve.bind(this) this.reject = this.reject.bind(this) } //进行代码的优化 initValue(){ //记录状态和值的改变 //初始化值 this.value = null //终值 this.reason = null //拒因 this.state = 'pending' //状态 } resolve(value){ //成功后的一系列操做(状态的改变,成功回调的执行) if(this.state === 'pending'){ //状态进行改变 this.state = 'fulfilled' //执行成功的回调,把终值进行赋值 this.value = value } } reject(reason){ //失败后的一系列操做(状态的改变,失败回调的执行) if(this.state === 'pending'){ //状态进行改变 this.state = 'rejected' //执行成功的回调,把据因进行赋值 this.reason = reason } } then() {} } module.exports = Promise
<font face="楷体">test.js</font>
const Promise = require('./promise.js') new Promise((resolve, reject) => { console.log('早上好!') resolve(1) })
<font face="楷体">运行结果:</font>
早上好!
代码以下:
<font face="楷体">promise.js</font>
class Promise { constructor(executor){ //不能相信用户的输入,因此这里要作参数效验 if(typeof executor !== 'function'){ throw new TypeError('Promise resolver ${executor} is not a function') } this.initValue() this.initBind() executor(this.resolve,this.reject) } //绑定 this initBind(){ this.resolve = this.resolve.bind(this) this.reject = this.reject.bind(this) } //进行代码的优化 initValue(){ //记录状态和值的改变 //初始化值 this.value = null //终值 this.reason = null //拒因 this.state = 'pending' //状态 } resolve(value){ //成功后的一系列操做(状态的改变,成功回调的执行) if(this.state === 'pending'){ //状态进行改变 this.state = 'fulfilled' //执行成功的回调,把终值进行赋值 this.value = value } } reject(reason){ //失败后的一系列操做(状态的改变,失败回调的执行) if(this.state === 'pending'){ //状态进行改变 this.state = 'rejected' //执行成功的回调,把据因进行赋值 this.reason = reason } } then(onFulfilled, onRejected) { // 参数效验 if (typeof onFulfilled !== 'function'){ onFulfilled = function(value) { return value } } if (typeof onRejected !== 'function'){ onRejected = function(reason){ throw reason } } if(this.state === 'fulfilled'){ onFulfilled(this.value) } if(this.state === 'rejected'){ onRejected(this.reason) } } } module.exports = Promise
<font face="楷体">test.js</font>
const Promise = require('./promise.js') new Promise((resolve, reject) => { console.log('早上好!') resolve(1) }).then(value=> { console.log('value',value) },reason => { console.log('reason',value) })
<font face="楷体">运行结果:</font>
早上好! value 1
代码以下:
<font face="楷体">promise.js</font>
class Promise { constructor(executor){ //不能相信用户的输入,因此这里要作参数效验 if(typeof executor !== 'function'){ throw new TypeError('Promise resolver ${executor} is not a function') } this.initValue() this.initBind() executor(this.resolve,this.reject) } //绑定 this initBind(){ this.resolve = this.resolve.bind(this) this.reject = this.reject.bind(this) } //进行代码的优化 initValue(){ //记录状态和值的改变 //初始化值 this.value = null //终值 this.reason = null //拒因 this.state = Promise.PENDING //状态 } resolve(value){ //成功后的一系列操做(状态的改变,成功回调的执行) if(this.state === Promise.PENDING){ //状态进行改变 this.state = Promise.FULFILLED //执行成功的回调,把终值进行赋值 this.value = value } } reject(reason){ //失败后的一系列操做(状态的改变,失败回调的执行) if(this.state === 'pending'){ //状态进行改变 this.state = Promise.REJECTED //执行成功的回调,把据因进行赋值 this.reason = reason } } then(onFulfilled, onRejected) { // 参数效验 if (typeof onFulfilled !== 'function'){ onFulfilled = function(value) { return value } } if (typeof onRejected !== 'function'){ onRejected = function(reason){ throw reason } } if(this.state === Promise.FULFILLED){ onFulfilled(this.value) } if(this.state === Promise.REJECTED){ onRejected(this.reason) } } } Promise.PENDING = 'pending' Promise.FULFILLED = 'fulfilled' Promise.REJECTED = 'reject' module.exports = Promise
<font face="楷体">test.js</font>
const Promise = require('./promise.js') new Promise((resolve, reject) => { console.log('早上好!') resolve(1) }).then(value=> { console.log('value',value) },reason => { console.log('reason',value) })
<font face="楷体">运行结果:</font>
早上好! value 1
代码以下
<font face="楷体">index.js</font>
console.log('1') new Promise((resolve, reject) => { console.log('2') resolve(1) }).then(value => { console.log('4') console.log('value',value) },reason => { console.log('reason',reason) }) console.log('3')
<font face="楷体">运行结果:</font>
1 2 3 4 value 1
代码以下
<font face="楷体">test.js</font>
const Promise = require('./promise.js') console.log('1') new Promise((resolve, reject) => { console.log('2') resolve(1) }).then(value => { console.log('4')//当即执行了 console.log('value',value)//当即执行了 },reason => { console.log('reason',reason) }) console.log('3')
<font face="楷体">运行结果:</font>
1 2 4 value 1 3
在promise.js里面添加代码,利用setTimeout,再运行test.js
代码以下:
<font face="楷体">promise.js</font>
class Promise { constructor(executor){ //不能相信用户的输入,因此这里要作参数效验 if(typeof executor !== 'function'){ throw new TypeError('Promise resolver ${executor} is not a function') } this.initValue() this.initBind() try{ executor(this.resolve, this.reject) }catch(e){ this.reject(e) } } //绑定 this initBind(){ this.resolve = this.resolve.bind(this) this.reject = this.reject.bind(this) } //进行代码的优化 initValue(){ //记录状态和值的改变 //初始化值 this.value = null //终值 this.reason = null //拒因 this.state = Promise.PENDING //状态 } resolve(value){ //成功后的一系列操做(状态的改变,成功回调的执行) if(this.state === Promise.PENDING){ //状态进行改变 this.state = Promise.FULFILLED //执行成功的回调,把终值进行赋值 this.value = value } } reject(reason){ //失败后的一系列操做(状态的改变,失败回调的执行) if(this.state === 'pending'){ //状态进行改变 this.state = Promise.REJECTED //执行成功的回调,把据因进行赋值 this.reason = reason } } then(onFulfilled, onRejected) { // 参数效验 if (typeof onFulfilled !== 'function'){ onFulfilled = function(value) { return value } } if (typeof onRejected !== 'function'){ onRejected = function(reason){ throw reason } } if(this.state === Promise.FULFILLED){ setTimeout(() => { onFulfilled(this.value) }) } if(this.state === Promise.REJECTED){ setTimeout(() => { onRejected(this.reason) }) } } } Promise.PENDING = 'pending' Promise.FULFILLED = 'fulfilled' Promise.REJECTED = 'reject' module.exports = Promise
<font face="楷体">test.js</font>
const Promise = require('./promise.js') console.log('1') new Promise((resolve, reject) => { console.log('2') resolve(1) }).then(value => { console.log('4') console.log('value',value) },reason => { console.log('reason',reason) }) console.log('3')
<font face="楷体">运行结果:</font>
1 2 3 4 value 1
代码以下:
<font face="楷体">test.js</font>
const Promise = require('./promise.js') console.log('1') new Promise((resolve, reject) => { throw new Error('You write wrong') // console.log('2') resolve(1) }).then(value => { console.log('4') console.log('value',value) },reason => { console.log('reason',reason) }) console.log('3')
<font face="楷体">运行结果:</font>
1 3 reason Error: You write wrong
上边是直接在最外层进行一个抛出
代码以下:
<font face="楷体">index.js</font>
const Promise = require('./promise.js') console.log('1') new Promise((resolve, reject) => { throw new Error('You write wrong') // console.log('2') resolve(1) }).then(value => { console.log('4') console.log('value',value) },reason => { console.log('reason',reason) }) console.log('3')
<font face="楷体">运行结果:</font>
1 3 reason Error: You write wrong
代码以下:
<font face="楷体">test.js</font>
const Promise = require('./promise.js') console.log('1') new Promise((resolve, reject) => { setTimeout(() => { console.log('hello!') resolve(1) }) }).then(value => { console.log('4') console.log('value',value) },reason => { console.log('reason',reason) }) console.log('3')
<font face="楷体">运行结果:</font>
1 3 hello!
不知道你们有没有发现 '4' 没有执行,这是什么缘由呢?
由于此时并无直接进入setTimeout里面,而是进行了.then操做
咱们在promise.js里面看到,
此时.then操做的状态等于'pending',
它不等于'fulfilled',也不等于'reject',
因此它并无执行这两个回调函数中的任意一个,因此.then方法并无执行
怎么解决这个问题呢?
首先在promise.js里面确定要追加一个状态的判断
代码以下:
<font face="楷体">promise.js</font>
class Promise { constructor(executor){ //不能相信用户的输入,因此这里要作参数效验 if(typeof executor !== 'function'){ throw new TypeError('Promise resolver ${executor} is not a function') } this.initValue() this.initBind() try{ executor(this.resolve, this.reject) }catch(e){ this.reject(e) } } //绑定 this initBind(){ this.resolve = this.resolve.bind(this) this.reject = this.reject.bind(this) } //进行代码的优化 initValue(){ //记录状态和值的改变 //初始化值 this.value = null //终值 this.reason = null //拒因 this.state = Promise.PENDING //状态 this.onFulfilledCallbacks = []//成功回调 this.onRejectedCallbacks = [] //失败回调 } resolve(value){ //成功后的一系列操做(状态的改变,成功回调的执行) if(this.state === Promise.PENDING){ //状态进行改变 this.state = Promise.FULFILLED //执行成功的回调,把终值进行赋值 this.value = value //成功或者失败之后进行这两个数组的执行 this.onFulfilledCallbacks.forEach((fn) => fn(this.value) )} } reject(reason){ //失败后的一系列操做(状态的改变,失败回调的执行) if(this.state === 'pending'){ //状态进行改变 this.state = Promise.REJECTED //执行成功的回调,把据因进行赋值 this.reason = reason this.onRejectedCallbacks.forEach(fn => fn(this.reason)) } } then(onFulfilled, onRejected) { // 参数效验 if (typeof onFulfilled !== 'function'){ onFulfilled = function(value) { return value } } if (typeof onRejected !== 'function'){ onRejected = function(reason){ throw reason } } if(this.state === Promise.FULFILLED){ setTimeout(() => { onFulfilled(this.value) }) } if(this.state === Promise.REJECTED){ setTimeout(() => { onRejected(this.reason) }) } //在promise.js里面确定要追加一个状态的判断 if(this.state === Promise.PENDING){ this.onFulfilledCallbacks.push((value) => { setTimeout(() => { onFulfilled(value) }) }) this.onRejectedCallbacks.push((reason) => { setTimeout(() => { onRejected(this.reason) }) }) } } } Promise.PENDING = 'pending' Promise.FULFILLED = 'fulfilled' Promise.REJECTED = 'reject' module.exports = Promise
<font face="楷体">运行结果:</font>
1 3 hello! 4 value 1
代码以下:
<font face="楷体">index.js</font>
new Promise((resolve, reject) => { resolve(1) }) .then( value => { return 'good' + value }, reason => { console.log('reason',reason) } ) .then( value => { console.log('value',value) }, reason => { console.log('reason',reason) } )
<font face="楷体">运行结果:</font>
value good1
实现链式调用,且改变了后面的then的值,必须经过新的实例
代码以下:
<font face="楷体">index.js</font>
new Promise((resolve, reject) => { // throw new Error('You write wrong') // console.log('2') resolve(1) }) .then( value => { throw new Error('use') return 'good' + value }, reason => { console.log('reason',reason) } ) .then( value => { console.log('value',value) }, reason => { console.log('reason',reason) } )
<font face="楷体">promise.js</font>
class Promise { constructor(executor){ //不能相信用户的输入,因此这里要作参数效验 if(typeof executor !== 'function'){ throw new TypeError('Promise resolver ${executor} is not a function') } this.initValue() this.initBind() try{ executor(this.resolve, this.reject) }catch(e){ this.reject(e) } } //绑定 this initBind(){ this.resolve = this.resolve.bind(this) this.reject = this.reject.bind(this) } //进行代码的优化 initValue(){ //记录状态和值的改变 //初始化值 this.value = null //终值 this.reason = null //拒因 this.state = Promise.PENDING //状态 this.onFulfilledCallbacks = []//成功回调 this.onRejectedCallbacks = [] //失败回调 } resolve(value){ //成功后的一系列操做(状态的改变,成功回调的执行) if(this.state === Promise.PENDING){ //状态进行改变 this.state = Promise.FULFILLED //执行成功的回调,把终值进行赋值 this.value = value //成功或者失败之后进行这两个数组的执行 this.onFulfilledCallbacks.forEach((fn) => fn(this.value) )} } reject(reason){ //失败后的一系列操做(状态的改变,失败回调的执行) if(this.state === 'pending'){ //状态进行改变 this.state = Promise.REJECTED //执行成功的回调,把据因进行赋值 this.reason = reason this.onRejectedCallbacks.forEach(fn => fn(this.reason)) } } then(onFulfilled, onRejected) { // 参数效验 if (typeof onFulfilled !== 'function'){ onFulfilled = function(value) { return value } } if (typeof onRejected !== 'function'){ onRejected = function(reason){ throw reason } } // 实现链式调用,且改变了后面的then的值,必须经过新的实例 let promise2 = new Promise((resolve, reject) => { if(this.state === Promise.FULFILLED){ setTimeout(() => { try{ const x = onFulfilled(this.value) resolve(x) }catch(e){ reject(e) } }) } if(this.state === Promise.REJECTED){ setTimeout(() => { try{ const x = onRejected(this.reason) resolve(x) }catch(e){ reject(e) } }) } //在promise.js里面确定要追加一个状态的判断 if(this.state === Promise.PENDING){ this.onFulfilledCallbacks.push((value) => { setTimeout(() => { try{ const x = onFulfilled(value) resolve(x) }catch(e){ reject(e) } }) }) this.onRejectedCallbacks.push((reason) => { setTimeout(() => { try{ const x = onRejected(this.reason) resolve(x) }catch(e){ reject(e) } }) }) } }) return promise2 } } Promise.PENDING = 'pending' Promise.FULFILLED = 'fulfilled' Promise.REJECTED = 'reject' Promise.resolvePromise = function(promise2, x, resolve, reject){} module.exports = Promise
<font face="楷体">运行结果:</font>
reason Error: use
代码以下:
<font face="楷体">test.js</font>
const Promise = require('./promise.js') new Promise((resolve, reject) => { // throw new Error('You write wrong') // console.log('2') resolve(1) }) .then( value => { return new Promise((resolve) => { resolve(1) }) }, reason => { console.log('reason',reason) } ) .then( value => { console.log('value',value) }, reason => { console.log('reason',reason) } )
<font face="楷体">运行结果:</font>
value Promise { value: 1, reason: null, state: 'fulfilled', onFulfilledCallbacks: [], onRejectedCallbacks: [], resolve: [Function: bound resolve], reject: [Function: bound reject] }
<font face="楷体" color=#CD2626>分析结果可知:</font>
当x的值不是基本值的时候,而是promise实例得时候,必须等待这一个promise的时候结束,才能进行进一步执行
因此规范提出了一个解决方案
针对resolvePromise的具体解决过程
首先是判断promise2和x的值是不是相等的
若是相等的话,就抛出一个TypeError,是为了不循环调用的问题
咱们能够经过代码看一下:
<font face="楷体">index.js</font>
let p1 = new Promise((resolve) => { resolve(1) }) let p2 = p1.then(() => { return p2 })
<font face="楷体">运行结果:</font>
TypeError: Chaining cycle detected for promise
链式调用出现了问题
<font face="楷体">promise.js</font>
class Promise { constructor(executor) { // 参数校检 if (typeof executor !== 'function') { throw new TypeError(`Promise resolver ${executor} is not a function`) } this.initValue() this.initBind() try { executor(this.resolve, this.reject) } catch (e) { this.reject(e) } } // 绑定 this initBind() { this.resolve = this.resolve.bind(this) this.reject = this.reject.bind(this) } // 初始化值 initValue() { this.value = null // 终值 this.reason = null // 拒因 this.state = Promise.PENDING // 状态 this.onFulfilledCallbacks = [] // 成功回调 this.onRejectedCallbacks = [] // 失败回调 } resolve(value) { // 成功后的一系列操做(状态的改变, 成功回调的执行) if (this.state === Promise.PENDING) { this.state = Promise.FULFILLED this.value = value this.onFulfilledCallbacks.forEach(fn => fn(this.value)) } } reject(reason) { // 失败后的一系列操做(状态的改变, 失败回调的执行) if (this.state === 'pending') { this.state = Promise.REJECTED this.reason = reason this.onRejectedCallbacks.forEach(fn => fn(this.reason)) } } then(onFulfilled, onRejected) { // 参数校检 if (typeof onFulfilled !== 'function') { onFulfilled = function(value) { return value } } if (typeof onRejected !== 'function') { onRejected = function(reason) { throw reason } } // 实现链式调用, 且改变了后面then的值, 必须经过新的实例 let promise2 = new Promise((resolve, reject) => { if (this.state === Promise.FULFILLED) { setTimeout(() => { try { const x = onFulfilled(this.value) Promise.resolvePromise(promise2, x, resolve, reject) } catch (e) { reject(e) } }) } if (this.state === Promise.REJECTED) { setTimeout(() => { try { const x = onRejected(this.reason) Promise.resolvePromise(promise2, x, resolve, reject) } catch (e) { reject(e) } }) } if (this.state === Promise.PENDING) { this.onFulfilledCallbacks.push(value => { setTimeout(() => { try { const x = onFulfilled(value) Promise.resolvePromise(promise2, x, resolve, reject) } catch (e) { reject(e) } }) }) this.onRejectedCallbacks.push(reason => { setTimeout(() => { try { const x = onRejected(this.reason) Promise.resolvePromise(promise2, x, resolve, reject) } catch (e) { reject(e) } }) }) } }) return promise2 } } Promise.PENDING = 'pending' Promise.FULFILLED = 'fulfilled' Promise.REJECTED = 'reject' Promise.resolvePromise = function(promise2, x, resolve, reject) { // x 与 promise 相等 if (promise2 === x) { reject(new TypeError('Chaining cycle detected for promise')) } let called = false if (x instanceof Promise) { // 判断 x 为 Promise x.then( value => { Promise.resolvePromise(promise2, value, resolve, reject) }, reason => { reject(reason) } ) } else if (x !== null && (typeof x === 'object' || typeof x === 'function')) { // x 为对象或函数 try { const then = x.then if (typeof then === 'function') { then.call( x, value => { if (called) return called = true Promise.resolvePromise(promise2, value, resolve, reject) }, reason => { if (called) return called = true reject(reason) } ) } else { if (called) return called = true resolve(x) } } catch (e) { if (called) return called = true reject(e) } } else { resolve(x) } } module.exports = Promise
<font face="楷体">test.js</font>
const Promise = require('./promise.js') new Promise((resolve, reject) => { // throw new Error('You write wrong') // console.log('2') resolve(1) }) .then( value => { return new Promise((resolve) => { resolve(new Promise((resolve,reject) => { resolve('333') }) ) }) }, reason => { console.log('reason',reason) } ) .then( value => { console.log('then 2 value:',value) }, reason => { console.log('reason',reason) } )
<font face="楷体">运行结果:</font>
then 2 value: 333
咱们须要安装一个promises-aplus-tests
npm install promises-aplus-tests
用来测试本身的promise 符不符合promisesA+规范
把下边这段代码copy到promise.js里面
Promise.defer = Promise.deferred = function () { let dfd = {} dfd.promise = new Promise((resolve,reject)=>{ dfd.resolve = resolve; dfd.reject = reject; }); return dfd; } module.exports = Promise;
执行输入npx promises-aplus-tests 你要测试的文件(promise.js)
npx promises-aplus-tests promise.js
以上,咱们就完成了一个基于Promise A+规范的Promise
https://github.com/shifengming/promise
小伙伴们有兴趣能够手动写下面这些方法的实现
但愿看到文章的同窗都有收获!
文章要是有不对的地方还望指正!
最后祝你们都愈来愈优秀!
欢迎你们加入,一块儿学习前端,共同进步!