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()
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()
/**
* 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()
asyncIterator
自定义异步数据结构的遍历
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()
Promise.finally
ES9中Promise是如何“兜底”操作的?
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)
const input = {
a: 1,
b: 2,
c: 3,
d: 4,
g: 5
}
const { a, b, ...rest } = input
console.log(a, b, rest)
dotAll
dotAll增强.
判断是否启用了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)
断言匹配
先行断言 (?=exp)
?=exp匹配后面为exp的内容
let test = 'hello world'
console.log(test.match(/hello(?=\sworld)/))
后行断言 (?<=exp)
?<=exp匹配前面面为exp的内容
let test = 'hello world'
console.log(test.match(/(?<=hello\s)world/))
负向先行断言 (?>!exp)
后面不能出现
exp指定的内容
let test = '123hello world'
console.log(test.match(/hello(?!\swerld)/)) // 获取到后面不是空格+werld的hello
负向后行行断言 (?!exp)
前面不能出现
exp指定的内容
let test = '123hello world'
console.log(test.match(/(?<!helle\s)world/))
练习
let str = '$foo %foo foo'
console.log(str.replace(/(?<=\$)foo/g, 'bar'))
let str1 = '$12 is worth ¥123'
console.log(str1.match(/(?<=\$)(\d+)/))