面经 | ES6

ES6

Generator

  • 形式上:
function* genFun(...args){ // 规定了5个状态
	yeild async1(); // 有yeild限制,不会立刻执行async1()
	yeild async2();
	yeild fun3();
	yeild 4;
	return 5  // 隐式声明为yeild
}

let gen=genFun("start");
  • genFun返回一个可迭代对象。上述genFun虽然最终返回的是5,但打印genFun()得到的不是5,是一个可迭代对象。
  • 这个可迭代对象,不是通过let…of来迭代,而是通过next来迭代。虽然,这个对象是类对象,但如果通过let…of这样来迭代,会产生以下问题:1.上面有5个状态,会忽略return声明的那个状态,也就是这剩下四个了;2.立马执行,不会暂停。
  • 通过.next(lastYeildResult),执行每个状态,并暂停。“执行下一个yeild并暂停”的意思。
  • 简单过程
    • let gen=genFun("start")创建一个Generator对象;"start"作为函数参数传入。
    • let y1=gen.next(a1);指定下一个yeild并暂停,也就是执行async1()后暂停,返回async1()的结果。a1是上一个yeild的结果,显然,因为我们是第一次运行next,所以上一个yeild为undefined,该参数没有意义。
    • 继续let y2=gen.next(a2);执行到下一个yeild,也就是async2(),那么这个时候a2就是上一个yeild(express)的结果了,上一个yeild(express)为yeild async1,显然,不论express为什么,这里指定了a2,那么,也就是yeild(express)=a2。
function* foo(x) {
  var y = 2 * (yield (x + 1));
  var z = yield (y / 3);
  return (x + y + z);
}

var a = foo(5);
a.next() // Object{value:6, done:false}
a.next() // Object{value:NaN, done:false}
a.next() // Object{value:NaN, done:true}

var b = foo(5);
b.next() // { value:6, done:false }
b.next(12) // { value:8, done:false }
b.next(13) // { value:42, done:true }
  • 以此类推。
  • 这种题,就想象有一个列表:
  • let gen=[ yeild e1, yeild e2,…,yeild en];指针停留在下表为-1
  • gen.next(lastYeildResult)移动指针,执行下一个函数,并通过lastYeildResult告诉下一个函数,上一个yeild的结果是什么。

Promise对象

  • new Promise(excutor);excutor是一个函数,会立刻执行;
  • then里的回调函数,会进入微任务队列;then会返回一个的promise对象
  • await等到的是一定是一个已经resolved的Promise对象;
  • 掌握几个常见的api:.all .allSetteled .race
    • all 等待全部reslove,有一个为reject都会进入catch
    • allSetteled只要全部fullfiled了就可以进入then回调了
    • race取最先fullfiled的promise的结果

创建Promise

  • new Promise(excutor),excutor是一个函数,会立刻执行。可以接受两个入参resolve,reject。
  • Promise.resolve/reject()也会返回一个Promise对象
new Promise(()=>{})
new Promise((resolve)=>{})
new Promise((resolve,reject)=>{})
Promise.resolve();
Promise.reject();
  • 只写一个new Promise()会报错:Promise resolver undefined si not a funciton
  • new Promise((resolve)=>console.log(1))会立刻执行,输出1.

三个状态

pending resolve reject

// let p=new Promise() // 报错:Promise resolver undefined is not a function
let p1=new Promise(()=>{})
let p2=new Promise((resolve)=>{resolve("hi")})
let p3=new Promise((resolve,reject)=>{reject()})

console.log(p1,p2,p3) 
// Promise {<pending>} Promise {<fulfilled>: 'hi'} Promise {<rejected>: undefined}

resolve/reject 和微任务的关系

new Promise((resolve,reject)=>{
    console.log(1);
    resolve(); // then中的回调会进入微任务队列;
    console.log(2) // resolve()只会让then进入队列,不会打断2的输出
}).then(res=>{ // then返回一个新的Promise对象
    console.log(3)
});
// 1 2 3
  • 假设没有resolve();then中的函数不会进入微任务队列,也就是不会输出。

await

难点在于,await fun,如果fun是一个Promise对象的情况;需要考虑一直取then的情况

async function a1(){ 
    // return "hi"
    // return new Promise(()=>{})
    // return Promise.resolve();
}

async function a2(){
    await a1();
    console.log(1);
}

// main线程开始
a2();
Promise.resolve().then(()=>{
    console.log(2)
})
  • 首先思考一个问题,await是怎么实现等待的呢?
async function a2(){
    await a1(); // a1不是Promise
    console.log(1);
}
// 实际等同于
async function a2(){
    a1().then(res=>{
    	console.log(1);
    }}
}
  • 看懂上面的例子,就很好的理解了,为什么a1会立刻执行,然后1会进入微任务;
  • 假设res是一个Promise对象,也就是a1()是一个Promise对象会发生什么呢?
async function a2(){
    await a1();  // a1是Promise对象
    console.log(1);
}
// 实际等同于
async function a2(){
    a1().then(res=>{
    	res.then(res2=>{
    		console.log(1)
    	)
    }}
}
  • 假设a1()返回的是Promise对象,也就是res是一个Promise,那么就会继续then。
    • 注意,这里默认a1是用async标记的,假设a1没用async标记,即使a1返回的是promise对象,还是会被分解成这样,所以asynce标记a1的作用就是,不断得去取返回的值res,如果是promise,就接着嵌套,不断then,否则,只会then一次。
async function a2(){
    a1().then(res=>{
    	console.log(1);
    }}
}

反正,复制下面例子,判断对了,就算理解对了

 async function a1(){ // 返回的是promise的时候,有无async会有什么区别?
    // return "hi"
    // return new Promise(()=>{})
    // return Promise.resolve();
    // return new Promise((resolve)=>{
    //     console.log(3)
    //     resolve()
    // })
}

async function a2(){
    await a1();
    console.log(1);
}

a2();
Promise.resolve().then(()=>{
    console.log(2)
})

在这里插入图片描述
打印p就好理解了,p是一个promise对象,状态为fulfilled;所以无论何时then,都能读到他的fulfilled值:‘hi’;
在这里插入图片描述
reject是一样的道理:
在这里插入图片描述

set vs weakSet

  • 都是集合,只不过weakSet里面只能存引用类型的变量。
  • weakSet相对set的好处就是,可以避免内存泄漏。weakSet里面存的引用,假设这个引用在外面被销毁了,那么weakSet里面的引用也会消失,就可以避免内存泄漏。
    • 内存泄漏:某块内存,程序不再使用,但还是没有被释放。

map vs weakMap

  • weak的表现和上面的一样,只不过之表现在key.key引用消失了,weakMap就删除键值对了.但是,value引用消失了,不影响.
  • map和weakMap的区别是key;weakMap只允许对象,其实也就是弱引用做为键.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值