乐趣区

关于前端:这份前端面试题能帮助的不止是你promise问题还能拿到大厂腾讯字节阿里实习offer

前言

小编之前写过一篇:前端面试之问到 promise 怎么办?,温故而知新哦

怎么明天又来一篇与 promise 的文章呢,哈哈哈哈小伙伴们不要急着来到哈,是因为意识了一个去找实习的同学,聊了实习找的怎么了,让我印象最粗浅的就是她讲 promise 的面试题,她说一面完结后就晓得凉凉了,并且要是有机会很想和面试官说一句:面试官对不起!我终于会了 Promise!

大略是这么个状况,所以呀小编又来讲讲 promise,前面带有面试题。同学加入的是某大厂面试,大家看看面试题及同学的答复就晓得这位同学有多好受了。

面试题

  • CSS 实现程度垂直居中
  • flex 的属性
  • CSS transition 的实现成果和有哪些属性
  • CSS 实现沿 Y 轴旋转 360 度(间接自爆了 CSS 不行 …. 麻了)
  • 好,那来点 JS 根本数据类型有哪些 用什么判断
  • 数组怎么判断
  • 援用类型和根本类型的区别
  • 什么是栈?什么是堆?
  • 手写 翻转字符串
  • 手写 Sum(1,2,3)的累加(argument)(我认为是柯里化,面试官笑了一下,脑筋不要这么死嘛)
  • 箭头函数和一般函数的区别(上题遗记了 argument,面试官特意问这个问题揭示我,奈何根底太差救不起来了 … 泪目)
  • 数组去重的办法
  • 图片懒加载
  • 跨域产生的起因,同源策略是什么
  • 说说你理解的解决办法(只说了 JSONP 和 CORS)
  • Cookie、sessionStorage、localStorage 的区别
  • get 和 post 的区别(只说了传参形式和性能不同,面试官问还有吗 其余的不晓得了 …)
  • 问了一下我的项目,react
  • 对 ES6 的理解(Promise 果然逃不了 ….)
  • let var const 的区别
  • 晓得 Promise 嘛?聊聊对 Promise 的了解?(说了一下 Promise 对象代表一个异步操作,有三种状态,状态转变为单向 …)
  • 那它是为了解决什么问题的?(emmm 当异步返回值又须要期待另一个异步就会嵌套回调,Promise 能够解决这个回调天堂问题)
  • 那它是如何解决回调天堂的?(Promise 对象外部是同步的,外部失去外部值后进行调用.then 的异步操作,能够始终.then .then …)
  • 好,你说能够始终.then .then … 那它是如何实现始终.then 的?(emmm… 这个.then 链式调用就是 … 额这个 …)
  • Promise 有哪些办法 all 和 race 区别是什么
  • 具体说一下 .catch() 和 reject(… 我人麻了 …)

完结环节

  • 问了面试官对 CSS 的了解(必须但非重要,前端的外围还是尽量一比一还原设计稿,只有写好了页面能力思考交互)
  • 如何学习(根底是最重要的,CSS 和 JS 要重视实际,盖房子最重要的还是地基,所有的框架源码,组件等都基于 CSS 和 JS)
  • 已经是如何度过这个过程的(多做我的项目,在我的项目中学习了解每个细节,再次告诫我根底的重要性)

Promise 概述

Promise 是 ES6 新增的援用类型,能够通过 new 来进行实例化对象。Promise 外部蕴含着异步的操作。

new Promise(fn)

Promise.resolve(fn)

这两种形式都会返回一个 Promise 对象。

  • Promise 有三种状态:期待态(Pending)、执行态(Fulfilled)和回绝态(Rejected),且 Promise 必须为三种状态之一只有异步操作的后果,能够决定以后是哪一种状态,任何其余操作都无奈扭转这个状态。
  • 状态只能由 Pending 变为 Fulfilled 或由 Pending 变为 Rejected,且状态扭转之后不会在发生变化,会始终放弃这个状态。
  • Pending 变为 Fulfilled 会失去一个公有value,Pending 变为 Rejected 会失去一个公有reason,当 Promise 达到了 Fulfilled 或 Rejected 时,执行的异步代码会接管到这个 value 或 reason。

晓得了这些,咱们能够失去上面的代码:

实现原理

class Promise {constructor() {
        this.state = 'pending'  // 初始化 未实现状态 
        // 胜利的值
        this.value = undefined;
        // 失败的起因
        this.reason = undefined;
    }
}
复制代码

根本用法

Promise 状态只能在外部进行操作,外部操作在 Promise 执行器函数执行。Promise 必须承受一个函数作为参数,咱们称该函数为执行器函数,执行器函数又蕴含 resolve 和 reject 两个参数,它们是两个函数。

  • resolve : 将 Promise 对象的状态从 Pending(进行中) 变为 Fulfilled(已胜利)
  • reject : 将 Promise 对象的状态从 Pending(进行中) 变为 Rejected(已失败),并抛出谬误。

应用栗子

let p1 = new Promise((resolve,reject) => {resolve(value);
})
setTimeout(() => {console.log((p1)); // Promise {<fulfilled>: undefined}
},1)   

let p2 = new Promise((resolve,reject) => {reject(reason);
})
setTimeout(() => {console.log((p2)); // Promise {<rejected>: undefined}
},1) 
复制代码

实现原理

  • p1 resolve 为胜利,接管参数 value,状态扭转为 fulfilled,不可再次扭转。
  • p2 reject 为失败,接管参数 reason,状态扭转为 rejected,不可再次扭转。
  • 如果 executor 执行器函数执行报错,间接执行 reject。

所以失去如下代码:

class Promise{constructor(executor){
      // 初始化 state 为期待态
      this.state = 'pending';
      // 胜利的值
      this.value = undefined;
      // 失败的起因
      this.reason = undefined;
      let resolve = value => {console.log(value);
        if (this.state === 'pending') {
          // resolve 调用后,state 转化为胜利态
          console.log('fulfilled 状态被执行');
          this.state = 'fulfilled';
          // 贮存胜利的值
          this.value = value;
        }
      };
      let reject = reason => {console.log(reason);
        if (this.state === 'pending') {
          // reject 调用后,state 转化为失败态
          console.log('rejected 状态被执行');
          this.state = 'rejected';
          // 贮存失败的起因
          this.reason = reason;
        }
      };
      // 如果 执行器函数 执行报错,间接执行 reject
      try{executor(resolve, reject);
      } catch (err) {reject(err);
      }
    }
  }
复制代码

测验一下上述代码咯:

class Promise{...} // 上述代码

new Promise((resolve, reject) => {console.log(0);
    setTimeout(() => {resolve(10) // 1
        // reject('JS 我不爱你了') // 2
        // 可能有谬误
        // throw new Error('是你的错') // 3    
    }, 1000)
})
复制代码
  • 当执行代码 1 时输入为 0 后一秒输入 10fulfilled 状态被执行
  • 当执行代码 2 时输入为 0 后一秒输入 我不爱你了rejected 状态被执行
  • 当执行代码 3 时 抛出谬误 是你的错

.then 办法

promise.then(onFulfilled, onRejected)

  • 初始化 Promise 时,执行器函数曾经扭转了 Promise 的状态。且执行器函数是同步执行的。异步操作返回的数据(胜利的值和失败的起因)能够交给.then 解决,为 Promise 实例提供处理程序。
  • Promise 实例生成当前,能够用 then 办法别离指定 resolved 状态rejected 状态 的回调函数。这两个函数 onFulfilled,onRejected 都是可选的,不肯定要提供。如果提供,则会 Promise 别离进入 resolved 状态rejected 状态 时执行。
  • 而且任何传给 then 办法的 非函数类型参数 都会被静默疏忽。
  • then 办法必须返回一个 新的 promise 对象(实现链式调用的要害)

实现原理

  • Promise 只能转换最终状态一次,所以 onFulfilledonRejected两个参数的操作是 互斥
  • 当状态 state 为fulfilled,则执行onFulfilled,传入this.value。当状态 state 为rejected,则执行onRejected,传入this.reason
class Promise {constructor(executor) {
        this.state = 'pending'  // 初始化 未实现状态 
        // 胜利的值
        this.value = undefined;
        // 失败的起因
        this.reason = undefined;

        // .then 立刻执行后 state 为 pengding  把.then 保存起来
        this.onResolvedCallbacks = [];
        this.onRejectedCallbacks = [];

        // 把异步工作 把后果交给 resolve
        let resolve = (value) => {if (this.state === 'pending') {console.log('fulfilled 状态被执行');
                this.value = value
                this.state = 'fulfilled'
                // onFulfilled 要执行一次
                this.onResolvedCallbacks.forEach(fn => fn());
            }
        }
        let reject = (reason) => {if (this.state === 'pending') {console.log('rejected 状态被执行');
                this.reason = reason
                this.state = 'rejected'
                this.onRejectedCallbacks.forEach(fn => fn());
            }
        }
        try {executor(resolve, reject)
        }
        catch (e) {reject(err)
        }
    }
    // 一个 promise 解决了后(实现状态转移,把控制权交进去)then(onFulfilled, onRejected) {if (this.state == 'pending') {this.onResolvedCallbacks.push(() => {onFulfilled(this.value)
            })
            this.onRejectedCallbacks.push(() => {onRejected(this.reason)
            })
        }
        console.log('then');
        // 状态为 fulfilled  执行胜利  传入胜利后的回调  把执行权转移
        if (this.state == 'fulfiiied') {onFulfilled(this.value);
        }
        // 状态为 rejected 执行失败  传入失败后的回调  把执行权转移
        if (this.state == 'rejected') {onRejected(this.reason)
        }
    }
}
let p1 = new Promise((resolve, reject) => {console.log(0);
    setTimeout(() => {// resolve(10)
        reject('JS 我不爱你了')
        console.log('setTimeout');    
    }, 1000)
}).then(null,(data) => {console.log(data, '++++++++++');
})
复制代码
0
then
rejected 状态被执行
JS 我不爱你了 ++++++++++
setTimeout
复制代码

当 resolve 在 setTomeout 内执行,then 时 state 还是 pending 期待状态 咱们就须要在 then 调用的时候,将胜利和失败存到各自的数组,一旦 reject 或者 resolve,就调用它们。

现能够异步实现了,然而还是不能链式调用啊?为保障 then 函数链式调用,then 须要返回 promise 实例,再把这个 promise 返回的值传入下一个 then 中。

Promise 的各种办法

Promise.prototype.catch()

catch 异样处理函数,解决后面回调中可能抛出的异样。只接管一个参数 onRejected 处理程序。它相当于调用 Promise.prototype.then(null,onRejected),所以它 也会返回一个新的 Promise

  • 例如
let p = new Promise((resolve, reject) => {setTimeout(() => {resolve(10)  
    }, 1000)
}).then(() => {throw Error("1123")
}).catch((err) => {console.log(err);
})
.then(() => {console.log('异样捕捉后能够持续.then');
})
复制代码

当第一个.then 的异样被捕捉后能够继续执行。

Promise.all()

Promise.all()创立的 Promise 会在这一组 Promise 全副解决后在解决。也就是说会期待所有的 promise 程序都返回后果之后执行后续的程序。返回一个新的 Promise。

  • 例如
let p1 = new Promise((resolve, reject) => {resolve('success1')
})

let p2 = new Promise((resolve, reject) => {resolve('success1')
})
// let p3 = Promise.reject('failed3')
Promise.all([p1, p2]).then((result) => {console.log(result)   // ['success1', 'success2']             

}).catch((error) => {console.log(error)
})
// Promise.all([p1,p3,p2]).then((result) => {//     console.log(result)
// }).catch((error) => {//     console.log(error) //  'failed3'     
//     
// })
复制代码

有上述例子失去,all 的性质:

  • 如果所有都胜利,则合成 Promise 的返回值就是所有子 Promise 的返回值数组。
  • 如果有一个失败,那么第一个失败的会把本人的理由作为合成 Promise 的失败理由。

Promise.race()

Promise.race()是一组汇合中最先解决或最先回绝的 Promise,返回一个新的 Promise。

  • 例如
let p1 = new Promise((resolve, reject) => {setTimeout(() => {resolve('success1')  
    },1000)
})

let p2 = new Promise((resolve, reject) => {setTimeout(() => {reject('failed2')  
    }, 1500)
})

Promise.race([p1, p2]).then((result) => {console.log(result)
}).catch((error) => {console.log(error)  //  'success1'    
})
复制代码

有上述例子失去,race 的性质:

  • 无论如何,最先执行实现的,就执行相应前面的.then 或者.catch。谁先以谁作为回调
    小编总结的这份 269 页的大厂前端面试题材料,Promise 相干的面试题也其中,小伙伴们请点击这里支付噢

总结

下面的 Promise 就总结到这里有什么了解也能够在下方评论区一起交流学习。

面试能够让本人发现更多的常识盲点,从而促成本人学习,大家一起加油冲呀!!

这篇文章小伙伴们也别忘了 点赞 + 评论 噢!!!

退出移动版