Promise规范及其应用

Promise解析

  • 什么是异步
  //异步执行
  let count = 1
  let timer = setTimeout(() => {
  count++
  console.log('in', count)
  }, 1000)
  console.log('out', count)
  // 循环执行+终止
  let count = 1
  let timer = setInterval(() => {
  count++
  console.log('in', count)
  }, 1000)
  console.log('out', count)
  setTimeout(() => {
  clearInterval(timer)
  }, 5000);

1.进程和线程

a.概念与区别

在这里插入图片描述
如上图所示,认为每个小区是一个单独的进程,cpu分配给每个小区居委资源,所以每个进程单独占有自己的资源,认为小区居委的不同工作人员是不同的线程,这些工作人员即线程占有当前小区即进程的共同资源,即线程间可以共享cpu资源。

进程是cpu资源分配的最小单位,线程是cpu调度的最小单位

b. 面试题:
  • 映射到前端: 浏览器。chrome新开的一个窗口,tab页是进程还是线程?
    答案:进程。 从概念上考虑,进程和线程的区别是进程拥有独立的资源,进程不会共享资源,而线程是共享所属进程的资源的,显然,两个tab之间并不共享资源,两个tab各自是独立的window,属于独立的两个进程。譬如,a页面陷入死循环,但b页面不会受到影响,因为他们并不在一个进程内。
  • 发散:
    方向一: 窗口(进程间)通信?浏览器的存储 - storage、cookie => 多种存储的区别
    方向二: 浏览器原理
    在这里插入图片描述
    浏览器在一个进程中有多个线程,即各种引擎。
  • GUI渲染引擎线程
  1. 解析HTML, CSS构建DOM树 =》 布局 =》 绘制
  2. 与JS引擎互斥 即执行JS线程时,GUI线程会pending,当任务队列空闲时才会再执行GUI线程
  • JS引擎线程
  1. 处理js 解析执行脚本
  2. 分配、处理、执行待执行的事件、event队列
  3. 阻塞GUI线程渲染
  • 定时器触发引擎线程
  1. 异步定时器处理与执行 setTimeout和setInterval
  2. 接收js引擎所分配的定时器任务,并计数
  3. 处理完成后交给事件触发线程触发
  • 异步HTTP请求线程
  1. 异步执行请求类处理,譬如Promise、ajax等
  2. 接收js引擎分配的异步http请求
  3. 监听回调,交给事件触发线程触发
  • 事件触发引擎线程
  1. 接收来源: 定时器、异步、用户操作
  2. 将回调过来的事件依次接入到任务队列队尾,返还给js引擎来执行

2. EVENT-LOOP

a. 执行堆栈

在这里插入图片描述

  • JS是单线程语言,单步执行
  function run() {
    func1()
  }

  function func1() {
    func2()
  }

  function func2() {
    throw new Error('please check your call stack')
  }

  run()
b. 面试题
  • js堆栈的执行顺序与堆栈溢出 =》 性能优化
  function func() {
    func()
  }
  func()

在这里插入图片描述

  • 执行顺序
setTimeout(() => {
  console.log('Time out')
})
Promise.resolve(1).then(() => {
  console.log('promise')
})
console.log('hi')
// h p t
### promise
#### a. 理论
```js
  // 1写一个异步定时
  setTimeout(()=>{
    console.log('Timeout')
  }, 2000)
  // 2写一个异步请求
  request.onreadystatechage = () => {
    if(request.readyState === 4) {
      const_status = request.state
      if(_status === 200) {
        const_res = request.responseText
        return sucess(_res)
      } esle {
        return fail(_status)
      }
    }
  }
  // 3延时后再请求
  setTimeout(()=>{
    console.log('Timeout')
    request.onreadystatechage = () => {
    if(request.readyState === 4) {
      const_status = request.state
      if(_status === 200) {
        const_res = request.responseText
        return sucess(_res)
      } esle {
        return fail(_status)
      }
    }
  }
  }, 2000)
  // 4再延时再请求  回调地狱
  setTimeout(()=>{
    console.log('Timeout')
    request.onreadystatechage = () => {
    if(request.readyState === 4) {
      const_status = request.state
      setTimeout(()=>{
    console.log('Timeout')
    request.onreadystatechage = () => {
    if(request.readyState === 4) {
      const_status = request.state
      if(_status === 200) {
        const_res = request.responseText
        return sucess(_res)
      } esle {
        return fail(_status)
      }
    }
  }
  }, 2000)
      if(_status === 200) {
        const_res = request.responseText
        return sucess(_res)
      } esle {
        return fail(_status)
      }
    }
  }
  }, 2000)
  // 5Promise的出现解决回调的流程无穷嵌套
  new Promise((resolve, reject) => {
    setTimeout(()=>{
      resolve('OK')
    }, 1000)
  }).then(r=>{
    console.log('then'+r)
  }).catch(err=>{
    console.log('catch'+err)
  })
  // 6多个异步任务顺序执行 =》 链式调用
  function wait500(input) {
    return new Promise(resolve, reject) => {
      setTimeout(()=> {
        resolve(input+500)
      }, 500)
    }
  }
  function wait1000(input) {
    return new Promise(resolve, reject) => {
      setTimeout(()=> {
        resolve(input+500)
      }, 1000)
    }
  }
  const p = new Promise((resolve, reject)=>{
    resolve(1)
  })
  p.then(wait500)
  .then(wait1000)
  .then(wait500)
  .then(wait1000)
  .then(result => {
    console.log('end'+result)
  })
  // 7全部执行完成后再操作
  Promise.all([wait500, wait1000]).then(result=>{
    consloe.log('all end', result)
  })
  // 8一但有执行完成的立刻操作
  Promise.race([wait500, wait1000]).then(result=>{
    consloe.log('race end', result)
  })
  // all和race的返回值是什么?
  // all返回一个数组包含全部的函数
  // race返回一个函数 即先执行完成的函数
b.面试题 手撕一个Promise

描述promise的框架

    1. promise有哪几种状态 - pending、fulfilled、rejected
    1. new Promise执行器executor()执行器参数是什么? - resolve和reject
    1. Promise的默认状态是什么?p promise的状态流转?p到f或r
    1. promise的value保存成功状态的枚举? -undefined、thenable、promsie
    1. 失败状态的值? - reason
      描述promise的接口
    1. promise一定有then,then接收来源? -两个回调 onfulfilled(value)+onrejected(reason)
// 三个状态 PENDING FUIFILLED REJECTED
const PENDING = 'PENDING'
const FULFILLED = 'FULFILLED'
const REJECTED = 'REJECTED'

class Promise {  //类
  constructor(executor) {  //构造函数
    //默认状态:PENDING
    this.status = PENDING
    // 成功状态的值
    this.value = undefined
    // 失败状态的值
    this.reason = undefined
    // 存放成功的回调
    this.onResolvedCallbacks = []
    // 存放失败的回调
    this.onRejectedCallbacks = []
    // 成功状态的回调
    let resolve = value => {
      if (this.status === PENDING) {
        this.status = FULFILLED
        this.value = value
        // 依次调用对应函数的执行
        (this.onResolvedCallbacks || []).forEach(fn => fn())
      }
    }
    // 失败状态的回调
    let reject = reason => {
      if (this.status === PENDING) {
        this.status = REJECTED
        this.reason = reason
      }
    }

    try {
      executor(resolve, reject)
    } catch (error) {
      reject(error)
    }  
  }

  then(onFulfilled, onRejcted) {
    if (this.status === FULFILLED) {
      onFulfilled(this.value)
    }
    if (this.status === REJECTED) {
      onRejcted(this.reason)
    }
    if (this.status === PENDING) {
      this.onResolvedCallbacks.push(()=>{
        onFulfilled(this.value)
      })
      this.onRejectedCallbacks.push(()=>{
        onRejcted(this.reason)
      })
    }
  }
}

const promise = new Promise((resolve, reject) => {
  resolve('成功')
}).then(data => {})
.catch(err => {})

// 启示 同步 =》 异步
// 顺序和空间的关系

补充知识点

  1. promise是一个具有then方法的对象,行为遵循promiseA+规范
  2. thenable是一个有then方法的函数或者对象
  3. value是promise状态成功时的值,即resolve的参数
  4. reason是promise状态失败时的值,即reject的参数 表示各种拒绝的原因
  5. exception异常值

规范

Promise States

有三种状态,

  1. pending 初始状态 可改变
    1.1. 一个promise在resolve或reject之前都处于这个状态
    1.2. 通过resolve可以把pendeing状态改为fulfilled状态
    1.3. 通过rejecte可以把pending状态改为rejected状态
  2. fulfilled
    2.1 最终态,不可变
    2.2 一个promise被resolve后会变成这个状态
    2.3 必须拥有一个value
  3. rejected
    3.1 最终态,不可变
    3.2 一个promise被reject后会变成这个状态
    3.3 必须拥有一个reason
    pending -> resolve(value) -> fulfilled
    pending -> reject(reason) -> rejected

then

promise应该有一个then方法 用来访问最终结果

promise.then(onFulfilled, onRejected)
  1. 参数要求
    1.1 onFulfilled应该是一个函数,如果不是则应该被忽略
    1.2 onRejected应该是一个函数,如果不是则应该被忽略
  2. onFulfilled特性
    2.1 当promise状态变成fulfilled时应该调用onFulfilled函数,参数就是value
    2.2 promise变成fulfilled之前不应该被调用
    2.3 只能被调用一次
  3. onRejected
    3.1 promise状态变成rejected时应该调用onRejected,参数就是reason
    3.2 promise状态变成rejected之前不应该被调用
    3.3 只能被调用一次
  4. onFulfilled和onRejected执行环境应该是微任务
  5. then方法可以被调用多次 ,其实就是链式调用
    5.1 promise状态变成fulfilled后,所有的onFulfilled回调都应该按照then的顺序执行
    5.2 promise状态变成rejected后,所有的onRejected回调都应该按照then的顺序执行
const promise = new Promise()
promise.then(cb1, cb2)
promise.then(cb1, cb2)
promise.then(cb1, cb2)
  1. 返回值
    then的返回值应该是一个promise,且是一个新的promise
    6.1 onFulfilled或者onRejected执行结果是x,调用resolvePromise()
    6.2 onFulfilled或者onRejected执行报错,promise2就需要被rejected
    6.3 onFulfilled不是一个函数,promise2以promise1的value触发fulfilled
    6.4 onRejected不是一个函数,promise2以promise1的reason触发rejected
const promise1 = new Promise()
const promise2 = promise.then(cb1, cb2)
promise2.then()
  1. resolvePromise
    7.1 promise2 === x, reject typeError
    7.2 如果x是一个promise
    pending
    fulfilled
    rejected
    7.3 对象或函数
    let then = x.then
resolvePromsie(promise, x, resolve, reject)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值