慕课前端售1299元的面试题【第一阶段】JS-day02


上一篇慕课css面试题,链接地址
下一篇慕课JS面试题,链接地址

1. js面试题

1. event loop事件循环机制

请添加图片描述
在这里插入图片描述

案例
在这里插入图片描述

  • console.log(‘Hi‘)先在 2.Call Stack中执行, 执行完清空,再走1.Browser console。输出 Hi
    在这里插入图片描述
  • setTimeout ( function cb1() ) ;先在 2.Call Stack中执行,进入 3.Web APIs,在此停留5s。
  • 并清除掉 2.Call Stack中的 setTimeout cb1。这里就执行结束了。
  • 往下执行console.log(‘Bye’)

-console.log('Bye‘)先在 2.Call Stack中执行, 执行完清空,再走 1.Browser console。输出 Bye

在这里插入图片描述

  • 到 Bye输出完,可执行代码全部执行完毕,2.Call Stack清空。此时 Timer cb1 还在 3.Web APIs中 5s还没到。
  • 此时启动Event loop 机制,同步代码执行完毕,2.Call Stack 空了。

解释:暂时没有代码可被推入Call Stack中,会立即启动Event loop机制,浏览器内核启动的事件循环机制。此时Event loop 会一遍一遍从(异步回调)Callback Queue中找,有没有函数了,有函数就拿过来。拿过来就推入 Call Stack中执行。

  • 一直等到 3,Web Apis中 Timer cb1定时器结束,推入4.Callback Queue中,并清除Web Apis的 Timer cb1。
  • 此时Event loop 发现 回调队列 Queue中有一个可执行函数,并推入 2.Call Stack中,Queue清除掉 cb1函数。
  • Call Stack中 现有 cb1函数,执行里面的 log.(‘cb1’) 并推入1.Browser console,控制台打印 cb1。并清除Call Stack中的log('cb1‘)
  • Call Stack 会在从cb1函数中寻找可执行的log,此时cb1函数中无任何可执行内容,清除掉cb1函数方法。

到此为止,整段代码执行完毕

浏览器控制台输出
Hi Bye cb1

在这里插入图片描述

在这里插入图片描述


2.Promise面试题

1.promise 的三种状态是什么?状态和变化

在这里插入图片描述

在这里插入图片描述

案例
在这里插入图片描述
在这里插入图片描述


2.then和cath改变状态

在这里插入图片描述

3. 请解答以下promise面试题

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


3. 手写promise 加载图片

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


4. async/await 和 promise的关系?

在这里插入图片描述
在这里插入图片描述

  • 案例

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  • 看如下题
    在这里插入图片描述
    const c 上 await如果要捕获错误可以使用 try catch捕获

在这里插入图片描述


5. 异步本质 ,看如下async/await顺序题?

在这里插入图片描述

  • 答案
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

3. 讲解宏任务 macroTask 和微任务 microTask ?

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  • 案例
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

4.手写Promise 函数,内容有点多

在这里插入图片描述

./MyPromise.js文件

class MyPromise {
    
    
  // 状态 [等待 实现了 拒绝了]
  state = 'pending' // 状态, 'pending' 'fulfilled' 'rejected'
  value = undefined // 成功后的值
  reason = undefined // 失败后的原因

  // 如果 resolve成功状态.then(fn1,fn2) 其中一个会被立即执行
  // 此时如果 p1.then(fn1,fn2) = pending状态.then(fn1,fn2) 
  // 这时就无法判断 fn1 和fn2那个先执行,就需要将如下俩函数,存储起来
  resolveCallbacks = [] // pending 状态下,储存成功的回调
  rejectCallbacks = [] // pending 状态下,储存失败的回调

  // 构造函数
  constructor(fn) {
    
    
    // 成功
    const resolveHandler = (value) => {
    
    
      if (this.state === 'pending') {
    
    
        this.state = 'fulfilled' // 修改 成功状态
        this.value = value // 修改成功后的值
        // 这里是用this.value ,value不会在闭包中,减少内存
        // 执行函数 resolveCallback
        this.resolveCallbacks.forEach(fn => fn(this.value))
      }
    }
    // 失败
    const rejectHandler = (reason) => {
    
    
      if (this.state === 'pending') {
    
    
        this.state = 'rejected' // 修改 失败状态
        this, reason = reason // 修改失败后的值
        this.rejectCallbacks.forEach(fn => fn(this.reason))
      }
    }
    //  try 中执行函数 ,catch中抛出错误,提升稳定性
    try {
    
    
      fn(resolveHandler, rejectHandler)
    } catch (err) {
    
    
      rejectHandler(err)
    }
  }

  // .then 会有成功回调,和失败回调
  // 当 pending 状态下,fn1 fn2 会被存储到 callbacks 中
  // callbacks 中就是 resolveCallback 或 rejectCallbacks
  then(fn1, fn2) {
    
    
    // 成功
    // 判断fn1 是否是一个函数,如果是返回它自己,如果不是给它一个函数,返回它自己
    fn1 = typeof fn1 === 'function' ? fn1 : (v) => v
    // 失败
    fn2 = typeof fn2 === 'function' ? fn2 : (e) => e

    // 判断状态
    // 等待时
    if (this.state === 'pending') {
    
    
      // 当前状态是pending,无法判断,只能先存储起来
      const p1 = new MyPromise((resolve, reject) => {
    
    
        this.resolveCallbacks.push(() => {
    
    
          try {
    
    
            const newValue = fn1(this.value)
            resolve(newValue) // p1.value 变成了新的promise 对象
          } catch (err) {
    
    
            reject(err)
          }
        })
        this.rejectCallbacks.push(() => {
    
    
          try {
    
    
            const newReason = fn2(this.reason)
            reject(newReason) // p1.reason 变成了新的promise 对象
          } catch (err) {
    
    
            reject(err)
          }
        })
      })
      return p1
    }
    // 成功
    if (this.state === 'fulfilled') {
    
    
      const p1 = new MyPromise((resolve, reject) => {
    
    
        try {
    
    
          const newValue = fn1(this.value)
          resolve(newValue)
        } catch (err) {
    
    
          reject(err)
        }
      })
      return p1
    }
    // 失败
    if (this.state === 'rejected') {
    
    
      const p1 = new MyPromise((resolve, reject) => {
    
    
        try {
    
    
          const newReason = fn2(this.reason)
          reject(newReason) // 其实它是 赋值给 p1.reason
        } catch (err) {
    
    
          reject(err)
        }
      })
      return p1
    }
  }
  //  .catch 只有 失败回调。就是 then 的一个语法糖,简单模式。
  catch(fn) {
    
    
    return this.then(null, fn)
  }
}

执行结果
在这里插入图片描述


1. promise.all 会怎样执行?
  • all代表全部。在这里promise需要全部都成功执行,再返回新的 promise,包含所有的输出结果。
<body>
  <h1>MyPromise.all 会怎样执行</h1>
  <script src="./MyPromise.js"></script>
  <script>
    const p1 = new MyPromise((resolve, reject) => {
    
    
      // resolve(100) // 成功
      // reject('错误信息...') // 失败
      // 宏任务,异步回调
      setTimeout(() => {
    
    
        resolve(100)
      }, 500)
    })
    const p2 = MyPromise.resolve(200)
    const p3 = MyPromise.resolve(300)
    const p4 = MyPromise.reject('错误信息...')
    // 传入 promise 数组,等待所有的都 fulfilled 之后,
    // 返回新 promise , 包含所有的结果 
    const p5 = MyPromise.all([p1, p2, p3])
    p5.then(result => console.log('all result', result))
  </script>
</body>

./MyPromise.js 文件中

MyPromise.all = function (promiseList = []) {
    
    

  const p1 = new MyPromise((resolve, reject) => {
    
    
    const result = [] // 存储 promiseList 所有的结果
    const length = promiseList.length // 记录 promise数组长度
    let resolvedCount = 0 // 用于计数

    // forEach 中不可使用 index,因为index是同步的,forEach会立即执行完
    promiseList.forEach(p => {
    
    
      // promise 有可能是同步有可能是异步,有可能等待一两秒才执行
      p.then(data => {
    
    
        result.push(data)

        // resolvedCount 必须在 then里面做++ 
        // 坚决不能使用 index
        resolvedCount++
        if (resolvedCount === length) {
    
    
          // 已经 遍历到了最后一个 promise
          resolve(result)
        }
      }).catch(err => {
    
    
        reject(err)
      })
    })
  })
  return p1
}

执行结果
在这里插入图片描述


2. promise.race 会怎样执行?

  • race 就是赛跑的意思,看那个promise跑的快就先执行那个,后面的舍弃
    在这里插入图片描述在这里插入图片描述在这里插入图片描述

DOM事件 和 event loop

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_46426412/article/details/130473937