二、异步编程笔记

web浏览器中有js线程,异步调用线程
在这里插入图片描述

promise中的then方法实际上是创建了新的proimse对象

macrotask(宏任务): setTimeout,setInterval
microtask(微任务): promise的回调,process.nextTick,mutationObserver

手写Promise源码

// 1.new Promise立即执行并且可以调用resolve和reject, resolve和reject会保存值,传递给then方法使用
// 2.三种状态,Pending,Fulfilled和 Rejected  状态不可逆
// 3.then 方法接受成功和失败的回调函数
// 4. promise中的then方法可以多次调用
// const promiseB = new Promise((resolve, reject) => {
//   resolve(1)
// })
// promiseB.then(data => {
//   console.log(data)
// })
// promiseB.then(data => {
//   console.log(data)
// })
// promiseB.then(data => {
//   console.log(data)
// })
// 5. then是链式调用的,then方法的返回值会传递给下一个then 方法,返回值可能是promise对象
// 如果then方法返回当前promise的话提示报错typeError
// 6. new Promise处理异常,new Promise执行的时候执行异常,成功调用的时候异常, 处理失败的时候异常
// 7. then中的参数是可选的可以不传递参数
//  new Promise((resolve , reject) => resolve(1)).then().then().then(value => console.log(value))
// 8. Promise.all的实现  根据数组的顺序返回解析过后的值,有一个reject就返回reject
// 9. Promise.resolve 相当于是个promise对象直接调用then方法
// 实现 : 如果是promise对象就直接返回promise, 如果是普通值就创建promise返回
// 9. finally中回调函数可以直接执行,return(可以return promise对象)之后,可以使用then方法接受finally中的return 

const PENDING = 'pending'
const FUFLILLED = 'fuflilled'
const REJECTED = 'rejected'

class MyPromise {
  constructor(executor) {
    try {
      executor(this.resolve, this.reject)
    } catch (error) {
      this.reject(error)
    }
  }

  // 定义初始状态
  status = PENDING

  // 接受resolve的初始值
  value = undefined

  // 接收失败的初始值
  reason = undefined

  // then 成功回调
  successCallback = []

  // then 失败回调
  failCallback = []

  resolve = (value) => {
    // 过程不可逆
    if (this.status !== PENDING) return

    // 修改状态
    this.status = FUFLILLED

    // 保存值
    this.value = value

    // 处理异步
    // this.successCallback && this.successCallback(value)
    while (this.successCallback.length) this.successCallback.shift()()
  }

  reject = (reason) => {
    // 过程不可逆
    if (this.status !== PENDING) return

    // 修改状态
    this.status = REJECTED

    // 保存值
    this.reason = reason

    // 处理异步
    // this.failCallback && this.failCallback(reason)
    while (this.failCallback.length) this.failCallback.shift()()
  }

  then (successCallback, failCallback) {
    // 处理then中参数是可选的,将参数传递到下一个then中
    successCallback = successCallback ? successCallback : value => value
    failCallback = failCallback ? failCallback : reason => { throw reason }

    let promise2 = new MyPromise((resolve, reject) => {
      if (this.status === FUFLILLED) {
        setTimeout(() => {
          try {
            let x = successCallback(this.value)
            resolvePromise(promise2, x, resolve, reject)
          } catch (error) {
            reject(error)
          }
        }, 0)
      } else if (this.status === REJECTED) {
        setTimeout(() => {
          try {
            let x = failCallback(this.reason)
            resolvePromise(promise2, x, resolve, reject)
          } catch (error) {
            reject(error)
          }
        }, 0)
      } else {
        // 处理异步 保存成功和失败回调
        this.successCallback.push(() => {
          setTimeout(() => {
            try {
              let x = successCallback(this.value)
              resolvePromise(promise2, x, resolve, reject)
            } catch (error) {
              reject(error)
            }
          }, 0)
        })
        this.failCallback.push(() => {
          setTimeout(() => {
            try {
              let x = failCallback(this.reason)
              resolvePromise(promise2, x, resolve, reject)
            } catch (error) {
              reject(error)
            }
          }, 0)
        })
      }
    })

    return promise2
  }

  finally (callback) {
    // 获取当前的promise的状态然后执行回调函数
    return this.then(value => {
      //  转换成promise对象,先执行callback然后再执行then
      return MyPromise.resolve(callback(value)).then(() => value)
    }, reason => {
      return MyPromise.resolve(callback(value)).then(() => { throw reason })
    })
  }

  catch (failCallback) {
    // 获取当前的promise的状态然后执行回调函数,不过这里只传递失败的回调
    return this.then(undefined, failCallback)
  }

  static all (arr) {
    let result = []
    // 解决异步调用的问题
    let index = 0
    return new MyPromise((resolve, reject) => {
      function addData (key, value) {
        result[key] = value
        index++
        if (index === result.length) {
          resolve(result)
        }
      }
      for (let i = 0;i < arr.length;i++) {
        let current = arr[i]
        if (current instanceof MyPromise) {
          // 是promise对象
          current.then(value => {
            addData(i, value)
          }, reason => reject(reason))
        } else {
          // 普通值
          addData(i, current)
        }
      }
    })
  }


  static resolve (value) {
    if (value instanceof MyPromise) return value
    return new MyPromise(resolve => resolve(value))
  }
}

// 解析promise
// 先判断是否是promise对象还是普通值,如果是普通值就直接resolve传递下去,如果是promise对象判断promise的状态之后,再将值传递下去
function resolvePromise (promise2, x, resolve, reject) {
  if (promise2 === x) {
    return reject(new TypeError('Uncaught (in promise) ReferenceError: Cannot access promise before initialization'))
  }
  if (x instanceof MyPromise) {
    // promise对象
    x.then(resolve, reject)
  } else {
    // 普通值
    resolve(x)
  }
}

module.exports = {
  MyPromise
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值