首页 > 其他分享 >深入理解ES6--迭代器、生成器、代理、反射、Promise

深入理解ES6--迭代器、生成器、代理、反射、Promise

时间:2023-03-13 12:31:45浏览次数:50  
标签:ES6 console log val -- 生成器 let new Promise


迭代器(Iterator)和生成器(Generator)

for-of循环展开运算符…都是针对迭代器的!!!

  • 不能使用箭头函数来创建生成器;ES6函数的简写方式可以(只需在函数名前加星号)
  • 可迭代对象具有Symbol.iterator属性,ES6中,所有的集合对象(数组、Set集合和Map集合)和字符串都是可迭代对象,这些对象都具有默认迭代器;
let collection = {
items: [],
*[Symbol.iterator]() {
for (let item of this.items) {
yield item
}
}
}
collection.items.push(1)
collection.items.push(2)
for (let x of collection) console.log(x) // 1 2

内建迭代器

  • entries() 返回一个迭代器,其值为多个键值对;
let ary = ['a', 'b']
let mySet = new Set(['a', 'b'])
let myMap = new Map().set('name', 'ligang').set('age', 28)
for (let entry of ary.entries()) console.log(entry) // [0, "a"][1, "b"]
for (let entry of mySet.entries()) console.log(entry) // ["a", "a"]["b", "b"]
for (let entry of myMap.entries()) console.log(entry) // ["name", "ligang"]["age", 28]
  • values() 返回一个迭代器,其值为集合的值;
  • keys() 返回一个迭代器,其值为集合中的所有键名

注意:数组和Set集合的默认迭代器是values();Map集合的默认迭代器是entries()

// Map集合可以使用解构
let myMap = new Map().set('name', 'ligang')
for (let [key, value] of myMap) console.log(key, value) // name ligang

展开运算符

展开运算符可以作用于可迭代对象,通过迭代器从对象中读取相应的值并插入到一个数组中。

let ary = ['a', 'b']
let mySet = new Set(['a', 'b'])
let myMap = new Map().set('name', 'ligang').set('age', 28)
console.log([...ary, 'c']) // ["a", "b", "c"]
console.log([...mySet]) // ["a", "b"]
console.log([...myMap]) // [["name", "ligang"], ["age", 28]]
特别说明:
ES6中展开运算符只针对iterable才起作用,默认有数组、set、map和字符串。**并不包含对象!**ES6规范中也并未将展开运算符支持对象,但是目前的主流浏览器Chrome和firefox均已实现该特性。这意味着如果想在低版本浏览器中使用需要特别的Babel插件进行转换!​​object-rest-spread​

深入理解ES6--迭代器、生成器、代理、反射、Promise_展开运算符

生成器返回值

展开运算符与for-of循环语句会直接忽略通过return语句指定的任何返回值,只要done变为true就立即停止读取其他的值!

function *createIterator() {
yield 1;
yield 2;
return 3;
}
let myIterator = createIterator();
console.log(myIterator.next()); // {value: 1, done: false}
console.log(myIterator.next()); // {value: 2, done: false}
console.log(myIterator.next()); // {value: 3, done: true}

let myIterator2 = createIterator();
for(let x of myIterator1) console.log(x) // 1 2

let myIterator3 = createIterator();
console.log([..myIterator3]) // [1, 2]

代理(Proxy)和反射(Reflections)

可以通过代理陷阱复制所有内建javascript对象的行为,当操作发生时,这些陷阱会被自动调用;反射API使开发者能够实现每个代理的默认行为。
区分参数trapTarget和receiver

let target = {
name: 'lg'
}
let proxy = new Proxy(target, {
get(trapTarget, key, receiver) {
console.log(Object.is(target, trapTarget)) // true
console.log(Object.is(target, receiver)) // false
if(!(key in receiver)) {
throw new TypeError(`属性${key}不存在`)
}
return Reflect.get(trapTarget, key, receiver)
}
})
console.log(proxy.name) // 'lg'
  • trapTarget:用于接收属性(代理的目标)的对象;
  • receiver:操作发生的对象(通常是代理)

注意:​key in receiver​​​要使用receiver,不要使用trapTarget,因为​​key in trapTarget​​会出发has陷阱!

基础proxy和reflect用法请查看:​​javascript:void(0)​​

Promise与异步编程

博客中已好多地方提及Promise相关的知识

  • ​​Promise​​
  • ​​ES6—Promise​​
  • ​​Promise—API​​

Promise的使用场景

并行执行两个异步操作,当两个操作都结束时通知你;或者同时进行两个异步操作,只取优先完成的操作结果。在这些情况下,Promise是更好的选择!

Promise执行

Promise的执行器会立即执行,然后才执行后续流程中的代码。then中相关的代码并不会立即执行,因为完成或拒绝处理程序总是在执行器完成后被添加到任务队列的末尾。

let promise = new Promise((resolve, reject) => {
console.log(1)
resolve(2)
console.log(3)
})
promise.then(val => console.log(val))
console.log(4)
// 输出:1 => 3 => 4 => 2

Promise链的返回值

let p1 = new Promise((resolve, reject) => {
resolve(42)
})
p1.then((val) => {
console.log(val)
return val + 1
}).then(val => {
console.log(val)
})
// 输出42、43

Promise链中返回Promise

触发完成处理程序

let p1 = new Promise((resolve, reject) => {
resolve(42)
})
p1.then((val) => {
console.log(val)
let p2 = new Promise((resolve, reject) => {
resolve(43)
})
return p2
}).then(val => console.log(val))
// 输出42、43

触发拒绝处理程序

let p1 = new Promise((resolve, reject) => {
resolve(42)
})
p1.then((val) => {
console.log(val)
let p2 = new Promise((resolve, reject) => {
reject('error')
})
return p2
}).then(val => console.log(val))
.catch(err => console.error(err))
// 输出42、error

捕获错误

在Promise的末尾留有一个拒绝处理程序可以确保能够正确处理素有可能发生的错误。

Promise.reject('Error')
.then(() => console.log(1))
.then(() => console.log(2))
.catch(err => console.log(err))
// 输出:Error,1、2并不会输出
Promise.resolve('1')
.then(val => console.log(val))
.then(() => {throw new Error('error')})
.then(() => console.log(2))
.catch(err => console.log(err))
// 输出:1、Error,2并不会输出

全局的拒绝处理

Node环境

  • ​unhandledRejection​​:当promise失败(rejected),但又没有处理时触发;
  • ​rejectionHandled​​:当promise失败(rejected),被处理时触发。
process.on('unhandledRejection', function(reason, promise){})
process.on('rejectionHandled', function(reason, promise){})

浏览器环境

  • ​unhandledrejection​​:当promise失败(rejected),但又没有处理时触发;
  • ​rejectionhandled​​:当promise失败(rejected),被处理时触发。
window.onunhandledrejection = function(event) {console.log(event, '...')}
window.onrejectionhandled = function(event) {console.log(event, '...')}

示例

window.addEventListener('unhandledrejection', event => {
// Prevent error output on the console:
event.preventDefault();
console.log('Reason: ' + event.reason);
});
window.addEventListener('rejectionhandled', event => {
console.log('REJECTIONHANDLED');
});

function foo() {
return Promise.reject('abc');
}
var r = foo();
setTimeout(() => {
r.catch(e => {});
}, 0);
// Reason: abc
// REJECTIONHANDLED


标签:ES6,console,log,val,--,生成器,let,new,Promise
From: https://blog.51cto.com/u_15998238/6117530

相关文章

  • 深入理解ES6--Set、Map及Symbol
    Set集合和Map集合Set集合是一种无重复元素的列表,通常用来检测给定的值在某个集合中是否存在;Map集合内含多组键值对,通常用来缓存频繁取用的数据。ES5中的问题varmap=Objec......
  • 2_Servlet初识
    ​ Servlet开发流程在后台随机生成一个整数当浏览器请求一个Servlet时如果生成的是奇数,返回"happynewyear"如果生成的是偶数,返回"happybirthday"1创建一个JAVA......
  • 脑瘫A+B问题(官方的题目-_-)
    1importjava.util.*;23publicclassMain4{publicstaticvoidmain(Stringargs[]){5Scannerscanner=newScanner(System.in);6......
  • 2_Servlet初识
    ​ Servlet开发流程在后台随机生成一个整数当浏览器请求一个Servlet时如果生成的是奇数,返回"happynewyear"如果生成的是偶数,返回"happybirthday"1创建一个JAVA......
  • Docker设置JDK17的JVM启动参数踩坑
    背景需求中需要接入腾讯广告的SDK,在编写完代码进行自测时,直接报错,提示Unabletomakeprotectedfinaljava.lang.Classjava.lang.ClassLoader.defineClass堆栈信息如......
  • SpringBoot--过滤器/拦截器/AOP--区别/使用/顺序
    SpringBoot--过滤器/拦截器/AOP--区别/使用/顺序https://knife.blog.csdn.net/article/details/121387483?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant......
  • linux安装tomcat
    linux安装tomcat一、下载安装包链接:https://pan.baidu.com/s/1TibyDHGbwc3YIEX0ZDJ8jg提取码:183q需要用到其他版本的tomcat,请自行下载:下载地址:http://tom......
  • 特殊回文数
    1importjava.util.*;23publicclassMain{4publicstaticvoidmain(String[]args){5Scannerscanner=newScanner(System.in);6......
  • HUSTOJ后台公告KindEditor编辑器中文件上传类型限制修改
    1.进入Ubuntu系统,/home/judge/src/web目录2.搜索找到KindEditor文件夹3.进入PHP文件夹,打开upload_json.php4.按照提示找到限制上传文件类型的代码,添加相应文件扩展名即......
  • CentOS-8源安装更新
    参考博文:https://developer.aliyun.com/mirror/centosrm/etc/yum.repos.d/CentOS-* 所有文件全部删除wget-O/etc/yum.repos.d/CentOS-Base.repohttps://mirrors.al......