自学内容网 自学内容网

ES9(2018)新增特性(七)

异步迭代

await可以和for...of循环一起使用,以串行的方式运行异步操作

async function process(array){
    for await(let i of array){
        // dosomething(i);
    }
}

forEach:循环中使用 await 的写法(不生效):

array.forEach(async (item)=>{
        let datas = await dosomething(item)
})

for of 使用 await 有效的(非并发) 

async function execute() {
    for (const item of arr) {
        let datas = await dosomething(item)
    }
 
}

for await of 使用await 有效的 (并发)

async function execute() {
     let index = 0
     for await (const item of arr) {
          dosomething(item)
     }
 }

Promise.finally()

Promise 对象的finally()方法用于在Promise成功或拒绝时使用

不管promise最后的状态,在执行完then或catch指定的回调函数以后,都会执行finally方法指定的回调函数,它可以防止Promise的then()和catch()方法中的代码重复

let promise = new Promise((resolve,reject) => {
    resolve('resolve')
})
promise.then((res) => {
    console.log(res)
}).catch((err) => {
    console.log(err)
}).finally(()=> {
    console.log('this finally')
})
// resolve
// this finally

使用场景

平常在工作中经常会遇到一些加载loading的需求,一般都在请求前设置loading展示,请求完成后关闭loading,刚开始我下意识把关闭loading放到then方法里面去处理,发现如果请求出现错误的情况,页面loading是还在的,就需要在catch方法里重写一遍导致代码重复,后面才了解到finally方法可以处理Promise的then和catch方法中代码重复的功能。

Rest/Spread 属性

Rest/Spread‌属性‌是主要用于处理对象和数组的操作。

Rest属性

Rest属性‌(用三个点表示,即...)主要用于对象解构和参数定义中。它的主要作用是将剩余的属性或参数收集到一个新的对象或数组中。

在对象解构中的应用‌:Rest操作符可以将一个对象中未被明确指定的属性收集到一个新的对象中。例如:

const obj = { a: 1, b: 2, c: 3 };
const { a, ...rest } = obj; // rest = { b: 2, c: 3 }

// 在这个例子中,a被明确指定,而b和c则被收集到rest对象中‌。

在函数参数中的应用‌:Rest操作符可以用于函数定义中,将多个参数收集为一个数组。例如:

function sum(...args) {
  return args.reduce((acc, curr) => acc + curr, 0);
}
console.log(sum(1, 2, 3)); // 输出6

// 在这个例子中,1、2和3被收集到args数组中,然后通过reduce方法计算它们的和‌。

Spread属性

Spread属性‌(同样用三个点表示,即...)主要用于对象和数组的字面量展开、函数调用以及对象解构的默认值设置中。

在对象字面量中的应用‌:Spread操作符可以将一个对象的所有可枚举属性复制到另一个对象中。例如:

const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3 }; // obj2 = { a: 1, b: 2, c: 3 }

// 在这个例子中,obj1的所有属性被复制到obj2中,并且添加了新的属性c‌:3。

 在函数调用中的应用‌:Spread操作符可以将一个数组的所有元素作为单独的参数传递给函数。例如:

const arr = [1, 2, 3];
const sum = (a, b, c) => a + b + c;
console.log(sum(...arr)); // 输出6

// 在这个例子中,数组[1, 2, 3]被展开为单独的参数传递给sum函数‌。

正则表达式增加命名捕获组的特性

在ES9(ECMAScript 2018)中,正则表达式增加了命名捕获组的特性,这使得正则表达式的可读性和维护性得到了显著的提升。

命名捕获组的语法是使用(?<name>)来定义一个命名捕获组,其中name是组的名称

下面是一个使用命名捕获组的例子:


const regex = /^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$/;
const match = regex.exec('2023-03-15');
 
console.log(match.groups.year);    // 输出:2023
console.log(match.groups.month);   // 输出:03
console.log(match.groups.day);     // 输出:15

正则扩展-反向断言

断言的概念:断言是用来判断一个字符是否出现在字符串的某个位置,但不包括该字符本身。

断言的作用:

  • 可以提高正则表达式的匹配效率,减少不必要的匹配。
  •  可以提高代码的可读性。

正则表达式引入了“反向断言”的概念。这允许你在匹配文本时向后查找模式。反向断言使用(?<!(?!)语法,分别被称为“负向先行断言”和“正向先行断言”。

注解:

(?=p)、(?<=p)   p 前面(位置)、p 后面(位置)

(?!p)、(?<!p>)除了 p 前面(位置)、除了 p后面(位置)

 如果你想匹配不被括号包围的“foo”字符串,你可以使用如下正则表达式:

【这里的(?![^()]*\))是一个反向断言,它断言在“foo”之后不会有一个闭括号),除非该括号不是由一个开括号(开始的。】

/foo(?![^()]*\))/

如何使用反向断言来查找不在HTML标签内的URLs:

【我们使用了一个反向断言(?![^<>]*>)来确保URL后面没有紧跟着HTML标签的闭合尖括号>。这样就能够找到不在HTML标签内的URLs。】

const htmlContent = '<a href="https://example.com">Link</a> Other https://example2.com';
const regex = /https?:\/\/[^\s]+(?![^<>]*>)/g;
const urls = htmlContent.match(regex);
console.log(urls); // 输出: ['https://example2.com']

正则表达式dotAll模式

正则表达式中点 匹配除换行符外的任何单字符,标记 s 改变这种行为,允许行终止符的出现

为了使点(.)可以匹配任意字符,ES9 引入新的修饰符 s (dotAll模式),就是让(.) 可以匹配一切字符。

注:\s是单个的空白字符,换行符也算是空白字符,g表示全局匹配

let str = `<ul>
  <li>
      <a>肖生克的救赎</a>
      <p>上映日期: 1994-09-10</p>
  </li>
  <li>
      <a>阿甘正传</a>
      <p>上映日期: 1994-07-06</p>
  </li>
</ul>`
// 声明正则
// const reg = /<li>\s+<a>(.*?)<\/a>\s+<p>(.*?)<\/p>/
// 正则dotAll模式
const reg = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/gs
// 执行匹配
// const result = reg.exec(str)

let result
let data = []
while (result = reg.exec(str)) {
    data.push({title: result[1], date: result[2]})
}
// 输出结果
console.log(data)

上一章:ES7【2016】、ES8【2017】新增特性


原文地址:https://blog.csdn.net/Cshaosun/article/details/145198977

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!