Promise.prototype.finally.
许多promise
第三方库都有一个finally
方法,用于在promise
结束(不管成功还是失败)时的回调。
常见的场景是
- 关闭数据请求时的
laoding
状态 - 不管前面的操作成功或是失败,最后都要执行一个指定的回调函数操作
现在我们的官方Promise
标准已经支持了finally()
方法.用于指定不管 Promise
对象最后状态如何,都会执行的操作。
promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});
复制代码
上面代码中,不管 promise
最后的状态,在执行完then
或catch
指定的回调函数以后,都会执行finally
方法指定的回调函数。
更加详细内容请参考
按顺序完成异步操作(Asynchronous Iteration)
实际开发中,经常遇到一组异步操作,需要按照顺序完成。比如,依次远程读取一组 URL,然后按照读取的顺序输出结果。
场景: 如果你有一堆异步或普通函数都返回 promise,要求你一个接一个地执行,怎么办?
async function logInOrder(urls) {
// 并发读取远程URL
const textPromises = urls.map(async (url) => {
const response = await fetch(url);
return response.text();
});
// 按次序输出
for (const textPromise of textPromises) {
console.log(await textPromise);
}
}
复制代码
async function getData() {
const promises = [fetch("url1"), fetch("url2"), fetch("url3"), fetch("url4")];
for (const item of promises) {
// 打印出promise
console.log(item);
}
for await (const item of promises) {
// 打印出请求的结果
console.log(item);
}
}
复制代码
区别
async function printFiles() {
const files = await getFilePaths();
for (const file of files) {
const contents = await fs.readFile(file, "utf8");
console.log(contents);
}
}
复制代码
async function printFiles() {
const files =
for (const file of await files) {
console.log(file);
}
}
复制代码
async function printFiles() {
const files = await getFilePaths();
await Promise.all(
files.map(async (file) => {
const contents = await fs.readFile(file, "utf8");
console.log(contents);
}),
);
}
复制代码
为对象支持扩展运算符(Rest/Spread Properties.)
ES6 为数组引入了扩展运算符的写法, 在 ES2018 中,为对象也引入了此写法
const obj = { a: "a", b: "b", c: "c", d: "d", e: "e" };
// 对象解构
const { a, b, c, ...rest } = obj;
// 组成新对象
const newObj = { a, ...rest };
复制代码
// bad ?
const test1 = this.data.test1;
const test2 = this.data.test2;
const test2 = this.data.test3;
// better ?
const { test1, test2, test3 } = this.data;
复制代码
更加详细内容请参考
解除模板字面量限制(Lifting template literal restriction).
ES2018 放松了对标签模板里面的字符串转义的限制。如果遇到不合法的字符串转义,就返回undefined
,而不是报错,并且从raw
属性上面可以得到原始字符串。
function tag(strs) {
strs[0] === undefined
strs.raw[0] === "\\unicode and \\u{55}";
}
tag`\unicode and \u{55}`
复制代码
上面代码中,模板字符串原本是应该报错的,但是由于放松了对字符串转义的限制,所以不报错了,JavaScript 引擎将第一个字符设置为undefined
,但是raw
属性依然可以得到原始字符串,因此tag
函数还是可以对原字符串进行处理。
正则之 s 修饰符:dotAll 模式-(s (dotAll) flag for regular expressions).
ES2018 引入 s
修饰符,使得.
可以匹配任意单个字符。
让点可以真正匹配任意单个字符
const reg = /./;
console.log(reg.test("5")); // true
console.log(reg.test("x")); // true
console.log(reg.test("\n")); // 换行符 false
console.log(reg.test("\r")); // 回车 false
console.log(reg.test("\u{2028}")); // 行分隔符 false
console.log(reg.test("\u{2029}")); // 段分隔符 false
const reg2 = /./s;
console.log(reg2.test("5")); // true
console.log(reg2.test("x")); // true
console.log(reg2.test("\n")); // true
console.log(reg2.test("\r")); // true
console.log(reg2.test("\u{2028}")); // true
console.log(reg2.test("\u{2029}")); // true
复制代码
/foo.bar/s.test("foo\nbar"); // true
复制代码
这被称为dotAll
模式,即点(dot)代表一切字符。所以,正则表达式还引入了一个dotAll
属性,返回一个布尔值,表示该正则表达式是否处在dotAll
模式。
正则之具名组匹配(RegExp named capture groups)
ES2018 引入了具名组匹配(Named Capture Groups),允许为每一个组匹配指定一个名字,既便于阅读代码,又便于引用。
ES2018 的案例
const date = /(\d{4})-(\d{2})-(\d{2})/.exec("2020-01-01");
console.log("date", date);
复制代码
这里 group 是没有数据的
通过 ?<>
来设置 group 的 key
最新的案例
const reg = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
console.log(reg.exec('2020-02-01'))\
const groups = reg.exec('2020-02-01').groups
const {year, month, day} = groups
console.log(year, month, day) // 2020 02 01
复制代码
const RE_DATE = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const matchObj = RE_DATE.exec("1999-12-31");
const year = matchObj.groups.year; // "1999"
const month = matchObj.groups.month; // "12"
const day = matchObj.groups.day; // "31"
复制代码
正则之后行断言(RegExp Lookbehind Assertions.)
ES2018 引入后行断言
“后行断言”指: x
只有不在y
后面才匹配,必须写成/(?<!y)x/
。比如,只匹配不在美元符号后面的数字,要写成/(?<!\$)\d+/
。
/(?<=\$)\d+/.exec('Benjamin Franklin is on the $100 bill') // ["100"]
/(?<!\$)\d+/.exec('it’s is worth about €90') // ["90"]
复制代码
使用后行断言进行字符串替换。
const RE_DOLLAR_PREFIX = /(?<=\$)foo/g;
"$foo %foo foo".replace(RE_DOLLAR_PREFIX, "bar");
// '$bar %foo foo'
复制代码
Unicode 属性类(RegExp Unicode Property Escapes)
ES2018 引入了一种新的类的写法\p{...}
和\P{...}
,允许正则表达式匹配符合 Unicode 某种属性的所有字符。
Unicode 属性转义在正则表达式中可使用\p
表示匹配,使用\P
表示不匹配
const regexGreekSymbol = /\p{Script=Greek}/u;
regexGreekSymbol.test("π"); // true
// 匹配所有空格
const reg = /\p{White_Space}/;
// 匹配所有的箭头字符
const regexArrows = /^\p{Block=Arrows}+$/u;
regexArrows.test("←↑→↓↔↕↖↗↘↙⇏⇐⇑⇒⇓⇔⇕⇖⇗⇘⇙⇧⇩"); // true
复制代码
最后
文章浅陋,欢迎各位看官评论区留下的你的见解!
觉得有收获的同学欢迎点赞,关注一波!