ES9(2018)基础知识

142 阅读2分钟

ES7~ES10.png 各大浏览器、平台支持ES的情况

ES9(2018)

For await of

ES9中异步操作集合是如何遍历的呢?

console.log(123);
/**
 * For await of
 * 
 */
function Gen(time) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(time)
        }, time);
    })
}
/***
 * for..of
 * 同步任务
 */
async function test() {
    let arr = [Gen(2000), Gen(100), Gen(3000)]
    for (const item of arr) {
        console.log(Date.now(), item.then(console.log));
    }
}
test()

image.png

console.log(123);
function Gen(time) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(time)
        }, time);
    })
}
/***
 * for..of
 * 同步任务
 */
async function test() {
    let arr = [Gen(2000), Gen(100), Gen(3000)]
    for (const item of arr) {
        console.log(Date.now(), await item.then(console.log));
    }
}
test()

image.png

/**
 * For await of
 * 
 */
function Gen(time) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(time)
        }, time);
    })
}
async function test() {
    let arr = [Gen(2000), Gen(100), Gen(3000)]
    for await (const item of arr) {
        console.log(Date.now(), item);
    }
}
test()
function Gen(time) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(time)
        }, time);
    })
}
async function test() {
    let arr = [Gen(2000), Gen(100), Gen(3000)]
    for (const item of arr) {
        console.log(Date.now(), await item);
    }
}
test()

image.png

asyncIterator

iterator

自定义异步数据结构的遍历

const obj = {
    count: 0,
    Gen(time) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve({ done: false, value: time })
            }, time);
        })
    },
    [Symbol.asyncIterator]() {
        let self = this
        return {
            next() {
                self.count++
                if (self.count < 4) {
                    return self.Gen(Math.random() * 1000)
                } else {
                    return Promise.resolve({
                        done: true,
                        value: ''
                    })
                }
            }
        }
    }
}
async function test() {
    for await (const item of obj) {
        console.log(Date.now(), item)
    }
}
test()

image.png

Promise.finally

ES9中Promise是如何“兜底”操作的?

Promise.finally--mdn

finally()  方法返回一个Promise。在promise结束时,无论结果是fulfilled或者是rejected,都会执行指定的回调函数。这为在Promise是否成功完成后都需要执行的代码提供了一种方式。

这避免了同样的语句需要在then()catch()中各写一次的情况。

const Gen = (time) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (time < 0.5) {
                reject(time)
            } else {
                resolve(time)
            }
        }, time);
    })
}
Gen(Math.random() * 1000)
    .then(val => {
        console.log('resolve', val);
    })
    .catch(err => {
        console.log('reject', err);
    })
    .finally(() => { console.log('finish'); })

Object的Rest&Spread方法

const input = {
  a: 1,
  b: 2
}
const output = {
  ...input,
  c: 3
}
console.log(input, output)
input.a = '2123'
console.log(input, output)

image.png

const input = {
  a: 1,
  b: 2,
  c: 3,
  d: 4,
  g: 5
}
const { a, b, ...rest } = input
console.log(a, b, rest)

image.png

dotAll

dotAll增强.

模式修饰

image.png

判断是否启用了dotAll模式

/***
 * 正则表达式中的点匹配不了:
 * 四个字节的utf字符
 * 行终止符
 * dotAll: s
 */
console.log(/foo.bar/.test('foo\nbar')) // false
console.log(/foo.bar/us.test('foo\nbar')) // true
const re = /foo.bar/s
// 判断是否开启了dotAll模式
console.log(re.dotAll) // true
console.log(re.flags) // s

命名分组捕获

// ES5
const t = '2019-06-07'.match(/(\d{4})-(\d{2})-(\d{2})/)
/**
 * ['2019-06-07', '2019', '06', '07', index: 0, input: '2019-06-07', groups: undefined]
 * 完整匹配
 * 第一个分组
 * 第二个分组
 * 第三个分组
 * index: 正则从第几个字符开始匹配
 * input: 完整的字符串
 * groups:
 */
console.log(t[1])

es9

const t = '2019-06-07'.match(/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/)
console.log(t)
console.log(t.groups.year)
console.log(t.groups.month)
console.log(t.groups.day)

image.png

断言匹配

断言匹配

先行断言 (?=exp)

?=exp 匹配后面为 exp 的内容

let test = 'hello world'
console.log(test.match(/hello(?=\sworld)/))

image.png

后行断言 (?<=exp)

?<=exp 匹配前面面为 exp 的内容

let test = 'hello world'
console.log(test.match(/(?<=hello\s)world/))

image.png

负向先行断言 (?>!exp)

后面不能出现 exp 指定的内容

let test = '123hello world'
console.log(test.match(/hello(?!\swerld)/)) // 获取到后面不是空格+werld的hello

image.png

负向后行行断言 (?!exp)

前面不能出现 exp 指定的内容

let test = '123hello world'
console.log(test.match(/(?<!helle\s)world/))

image.png

练习

image.png

let str = '$foo %foo foo'
console.log(str.replace(/(?<=\$)foo/g, 'bar'))
let str1 = '$12 is worth ¥123'
console.log(str1.match(/(?<=\$)(\d+)/))