手写promise

简介: 手写promise

基本结构

<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
 
<body>
    <script>
        class MyPromise {
            PromiseState = 'pending'
            PromiseResult = undefined
            constructor(executor) {
                // this指向将来new的实例对象
                //executor(函数1,函数2)
                try {
                    executor(this.resolve, this.reject)
                } catch (error) {
                    this.reject(error)
                }
 
            }
            //成功方法
            resolve = (val) => {
                if (this.PromiseState !== 'pending') return
                //成功状态
                this.PromiseState = 'fulfilled'
                //保存结果
                this.PromiseResult = val
            }
            //失败方法
            reject = (val) => {
                if (this.PromiseState !== 'pending') return
                //失败状态
                this.PromiseState = 'rejected'
                //保存结果
                this.PromiseResult = val
            }
 
        }
    </script>
//对比
    <script>
        let promise = new Promise((resolve, reject) => {
            //状态/结果
            // console.log('i love you ')
            resolve(100)
            // reject(100)
            // throw 400
        })
        console.log(promise)
    </script>
 
</body>
 
</html>
 
​//Promise的状态由
1.resolve
2.reject
3.throw
决定

在 JavaScript 中通过 queueMicrotask() 使用微任务 - Web API 接口参考 | MDN (mozilla.org)

<!DOCTYPE html>
<html lang="en">
 
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
 
<body>
  <script>
    class MyPromise {
      PromiseState = 'pending'
      PromiseResult = undefined
      //暂存两个回调,因为在调用时,可能有多个成功,失败的调用,then链式调用
      FulfilledCbs = []
      RejectedCbs = []
      constructor(executor) {
        // this指向将来new的实例对象
        //executor(函数1,函数2)
        try {
          executor(this.resolve, this.reject)
        } catch (error) {
          this.reject(error)
        }
 
      }
      //成功方法
      resolve = (val) => {
        if (this.PromiseState !== 'pending') return
        //成功状态
        this.PromiseState = 'fulfilled'
        //保存结果
        this.PromiseResult = val
        while (this.RejectedCbs.length) {
          //shift弹出来,length减1,0时while循环就结束了,没弹出执行后面加个括号shift()()
          this.RejectedCbs.shift()()
        }
      }
      //失败方法
      reject = (val) => {
        if (this.PromiseState !== 'pending') return
        //失败状态
        this.PromiseState = 'rejected'
        //保存结果
        this.PromiseResult = val
        while (this.FulfilledCbs.length) {
          //shift弹出来,length减1,0时while循环就结束了,没弹出执行后面加个括号shift()()
          this.FulfilledCbs.shift()()
        }
      }
      //接收两个回调
      // 如果当前promise对象为fulfilled 状态,执行回调一
      // 如果当前promise对象为rejected  状态,执行回调二
      // 如果当前promise对象为pending(待定) 状态,暂存两个回调
      //then 方法会返回新的promise对象,该对象的状态+结果由返回值决定
      /*返回值是promise 
      返回值为成功,新promise就是成功
      返回值为失败,新promise就是失败
          返回值非promise
      新promise就是成功,返回值就是返回值  
      */
      then(onFulfilled, onRejected) {
        //判断是否是函数,不是变成函数                                  val代表接收的promise=》原路返回
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val
        // 函数保持失败状态
        onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }
        // thenPromise新promise
        let thenPromise = new MyPromise((resolve, reject) => {
          const resolvePromise = (cb) => {
            queueMicrotask(() => {
              try {
                //把当前promise对象的值传入,进而使用
                let x = cb(this.PromiseResult)
                //如果是MyPromise对象\
                if (x === thenPromise) {
                  throw Error('不能返回自身')
                }
                if (x instanceof MyPromise) {
                  x.then(resolve, reject)
                } else {
                  resolve(x)
                }
 
              } catch (error) {
                reject(error)
              }
 
            })
          }
          if (this.PromiseState === 'fulfilled') {
 
            resolvePromise(onFulfilled)
          } else if (this.PromiseState === 'rejected') {
 
            resolvePromise(onRejected)
          } else if (this.PromiseState === 'pending') {
            //成功
            //将来调用时,把当前promise对象的值传入,进而使用
            this.FulfilledCbs.push(() => resolvePromise(this.onFulfilled))
            //失败
            this.RejectedCbs.push(() => resolvePromise(this.onRejected))
          }
 
        })
        return thenPromise
 
      }
 
      /*Promise.all()是个静态方法,参数是个数组
      返回一个promise
      数组中,所有promise对象都为成功,就返回成功状态
      数组中,只要有一个失败,就返回失败状态
      */
      static all(arr) {
        const result = []
        let n = 0
        return new Promise((resolve, reject) => {
          const addData = (index, val) => {
            result[index] = val
            n++
            if (n === arr.length) {
              resolve(result)
            }
          }
          arr.forEach((item, index) => {
            //判断是否是promise对象
            if (item instanceof MyPromise) {
              //resolve
              item.then(val => addData(index, val), reject)
            } else {
              addData(index, item)
            }
          })
        })
      }
 
      /* 
      race是静态方法
      返回一个promise
     数组中的字面量都视为成功的promise
     promise的状态+结果由参数数组中最快得到的结果决定
      */
      static race(val) {
        return new MyPromise((resolve, reject) => {
          arr.forEach(item => {
            if (item instanceof MyPromise) {
              item.then(resolve, reject)
            } else {
              //then是异步,为保证顺序,resolve(item)放到异步里
              queueMicrotask(() => {
                resolve(item)
              })
 
            }
          })
        })
      }
      /* 
      resolve是静态方法
      返回一个promise
      参数是promise对象,就原封不动返回该对象
      参数非promise对象,就返回一个成功的promise对象
      */
     
      /* 
      finally
      */
      finally(callback){
        return this.then(callback,callback).then(()=>this)
        
      }
      static resolve(val) {
        if (val instanceof MyPromise) return val
        return new MyPromise(resolve => resolve(val))
      }
      /* 
   reject是静态方法
   返回一个promise
   不管是什么,都会包裹为失败的promise对象,值PromiseResult就是传递的值
   */
      static reject(val) {
        return new MyPromise(_, reject(val => reject(val)))
      }
 
      /* 
      catch
      */
      catch(onRejected) {
        return this.then(_, onRejected)
      }
 
    }
    let my = new MyPromise()
    console.log(my)
  </script>
 
</body>
 
</html>
目录
相关文章
|
6月前
|
前端开发 JavaScript
在JavaScript中,什么是promise、怎么使用promise、怎么手写promise
在JavaScript中,什么是promise、怎么使用promise、怎么手写promise
99 4
|
前端开发
手写基础 promise
手写基础 promise
64 0
|
存储 前端开发
|
前端开发
Promise的用法&原理&手写实现-2
Promise的用法&原理&手写实现-2
40 1
|
6月前
|
前端开发 JavaScript
手写promise
手写promise
41 1
|
6月前
|
存储 前端开发 JavaScript
面试官:请手写一个Promise
面试官:请手写一个Promise
|
前端开发 JavaScript API
Promise的用法&原理&手写实现-1
Promise的用法&原理&手写实现-1
54 0
|
前端开发
手写Promise
手写Promise
|
前端开发 vr&ar
自定义手写Promise
手写函数版和类版Promise
55 0
|
前端开发 算法 安全
前端面试100道手写题(1)—— 手写Promise实现
今年的金三银四面试,遇到了很多新的面试八股文,其实心里对手写题或者算法题有一定抵触,因为实际工作中基本上就不会用到这些东西,但是正因为这些基础八股文,才能真正验证一个人对技术有多热爱的程度。也有可能近几年没有对这些基础知识进行巩固,所以干脆一狠心,先立个flag, 准备完成100道手写题。
254 0