async 和 await
async 和 await 两种语法结合可以让异步代码像同步代码一样
async 函数
-
async 函数的返回值为 promise 对象,
-
promise 对象的结果由 async 函数执行的返回值决定
//async 函数 async function fn() { // 1. 返回一个字符串 return '尚硅谷'; // 返回的结果不是一个 Promise 类型的对象, 返回的结果就是成功 Promise 对象 return; // 2. 抛出错误, 返回的结果是一个失败的 Promise throw new Error('出错啦!'); // 3. 返回的结果如果是一个 Promise 对象 return new Promise((resolve, reject) => { resolve('成功的数据'); // reject("失败的错误"); }); } const result = fn(); console.log(result); //调用 then 方法 result.then(value => { console.log(value); }, reason => { console.warn(reason); })
await 表达式
-
await 必须写在
async
函数中 -
await 右侧的表达式一般为
promise
对象 -
await 返回的是
promise
成功的值 -
await 的
promise
失败了, 就会抛出异常, 需要通过try...catch
捕获处理
//创建 promise 对象 const p = new Promise((resolve, reject) => { // resolve("用户数据"); reject("失败啦!"); }) // await 要放在 async 函数中. async function main() { try { let result = await p; //await 右侧的表达式一般为 `promise` 对象 console.log(result);//await 返回的是 `promise` 成功的值 } catch (e) { console.log(e);//await 的 `promise `失败了, 就会抛出异常, 需要通过 `try...catch` 捕获处理 } } //调用函数 main();
async和await结合读取文件
//1. 引入 fs 模块 const fs = require("fs"); //读取『为学』 function readWeiXue() { return new Promise((resolve, reject) => { fs.readFile("./resources/为学.md", (err, data) => { //如果失败 if (err) reject(err); //如果成功 resolve(data); }) }) } function readChaYangShi() { return new Promise((resolve, reject) => { fs.readFile("./resources/插秧诗.md", (err, data) => { //如果失败 if (err) reject(err); //如果成功 resolve(data); }) }) } function readGuanShu() { return new Promise((resolve, reject) => { fs.readFile("./resources/观书有感.md", (err, data) => { //如果失败 if (err) reject(err); //如果成功 resolve(data); }) }) } //声明一个 async 函数 async function main(){ //获取为学内容 let weixue = await readWeiXue(); //获取插秧诗内容 let chayang = await readChaYangShi(); // 获取观书有感 let guanshu = await readGuanShu(); console.log(weixue.toString()); console.log(chayang.toString()); console.log(guanshu.toString()); } main();
async与await封装AJAX请求
// 发送 AJAX 请求, 返回的结果是 Promise 对象 function sendAJAX(url) { return new Promise((resolve, reject) => { //1. 创建对象 const x = new XMLHttpRequest(); //2. 初始化 x.open('GET', url); //3. 发送 x.send(); //4. 事件绑定 x.onreadystatechange = function() { if (x.readyState === 4) { if (x.status >= 200 && x.status < 300) { //成功啦 resolve(x.response); } else { //如果失败 reject(x.status); } } } }) }
//promise then 方法测试 sendAJAX("https://api.apiopen.top/getJoke").then(value=>{ console.log(value); }, reason=>{})
// async 与 await 测试 axios async function main() { //发送 AJAX 请求 let result = await sendAJAX("https://api.apiopen.top/getJoke"); //再次测试 let tianqi = await sendAJAX( 'https://www.tianqiapi.com/api/?version=v1&city=%E5%8C%97%E4%BA%AC&appid=23941491&appsecret=TXoD5e8P') console.log(tianqi); } main();
对象方法扩展
声明对象
const school = { name:"尚硅谷", cities:['北京','上海','深圳'], xueke: ['前端','Java','大数据','运维'] };
Object.values 和 Object.entries
-
Object.values()方法返回一个给定对象的所有可枚举属性值的数组
//获取对象所有的键
console.log(Object.keys(school));
//获取对象所有的值
console.log(Object.values(school));
-
Object.entries()方法返回一个给定对象自身可遍历属性 [key,value] 的数组
//entries
console.log(Object.entries(school));
//创建 Mapconst m = new Map(Object.entries(school));
console.log(m.get('cities'));
Object.getOwnPropertyDescriptors
-
该方法返回指定对象所有自身属性的描述对象
//对象属性的描述对象 console.log(Object.getOwnPropertyDescriptors(school));
Rest 参数
Rest 参数与 spread 扩展运算符在 ES6 中已经引入,不过 ES6 中只针对于数组,在 ES9 中为对象提供了像数组一样的 rest 参数和扩展运算符
//rest 参数 function connect({host, port, ...user}){ console.log(host);//127.0.0.1 console.log(port);//3306 console.log(user);//root,root,master } connect({ host: '127.0.0.1', port: 3306, username: 'root', password: 'root', type: 'master' });
//对象合并 const skillOne = { q: '天音波' } const skillTwo = { w: '金钟罩' } const skillThree = { e: '天雷破' } const skillFour = { r: '猛龙摆尾' } const mangseng = {...skillOne, ...skillTwo, ...skillThree, ...skillFour}; console.log(mangseng)
正则扩展
命名捕获分组
正常正则
//声明一个字符串let str = '<a href="http://www.atguigu.com">尚硅谷</a>';
//提取 url 与 『标签文本』const reg = /<a href="(.*)">(.*)<\/a>/;
//执行const result = reg.exec(str);
console.log(result); console.log(result[1]); console.log(result[2]);
命名捕获
let str = '<a href="http://www.atguigu.com">尚硅谷</a>'; //分组命名 const reg = /<a href="(?<url>.*)">(?<text>.*)<\/a>/; const result = reg.exec(str); console.log(result.groups.url); console.log(result.groups.text);
正则断言
声明字符串
let str = 'JS5211314你知道么555啦啦啦';
正向断言
const reg = /\d+(?=啦)/; const result = reg.exec(str); console.log(result)
反向断言
const reg = /(?<=么)\d+/; const result = reg.exec(str); console.log(result);
正则-dotALL模式
dot . 元字符 除换行符以外的任意单个字符
let str = ` <ul> <li> <a>肖生克的救赎</a> <p>上映日期: 1994-09-10</p> </li> <li> <a>阿甘正传</a> <p>上映日期: 1994-07-06</p> </li> </ul>`; //声明正则 //未使用 dot 字符进行的正则匹配 const reg = /<li>\s+<a>(.*?)<\/a>\s+<p>(.*?)<\/p>/; //使用 dot 字符进行的正则匹配 s(模式修正符) const reg = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/gs; //执行匹配 let result; let data = []; while(result = reg.exec(str)){ data.push({title: result[1], time: result[2]}); } //输出结果 console.log(data);
方法扩展
对象(Object.fromEntries)
//二维数组 const result = Object.fromEntries([ ['name','尚硅谷'], ['xueke', 'Java,大数据,前端,云计算'] ]); //Map const m = new Map(); m.set('name','ATGUIGU'); const result = Object.fromEntries(m); //Object.entries ES8 const arr = Object.entries({ name: "尚硅谷" }) console.log(arr);
字符串
// trim let str = ' iloveyou '; console.log(str); console.log(str.trimStart()); console.log(str.trimEnd());
数组
//flat 平 //将多维数组转化为低维数组 const arr = [1,2,3,4,[5,6,[7,8,9]]]; //参数为深度 是一个数字 console.log(arr.flat(2));
//flatMap const arr = [1,2,3,4]; const result = arr.flatMap(item => [item * 10]); console.log(result);
Symbol.prototype.description
创建 Symbol let s = Symbol('尚硅谷');
console.log(s.description);
私有属性
class Person{ //公有属性 name; //私有属性 #age; #weight; //构造方法 constructor(name, age, weight){ this.name = name; this.#age = age; this.#weight = weight; } intro(){ console.log(this.name); console.log(this.#age); console.log(this.#weight); } } //实例化 const girl = new Person('晓红', 18, '45kg'); console.log(girl.name); // console.log(girl.#age); // console.log(girl.#weight); girl.intro();
Promise.allSettled
//声明两个promise对象 const p1 = new Promise((resolve, reject)=>{ setTimeout(()=>{ resolve('商品数据 - 1'); },1000) }); const p2 = new Promise((resolve, reject)=>{ setTimeout(()=>{ resolve('商品数据 - 2'); // reject('出错啦!'); },1000) }); //调用 allsettled 方法 const result = Promise.allSettled([p1, p2]); console.log(result) const res = Promise.all([p1, p2]); console.log(res)
String.prototype.matchAll
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>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/sg //调用方法 const result = str.matchAll(reg); // for(let v of result){ // console.log(v); // } const arr = [...result]; console.log(arr);
可选链操作符
?.
function main(config){ // const dbHost = config && config.db && config.db.host; const dbHost = config?.db?.host; console.log(dbHost); } main({ db: { host:'192.168.1.100', username: 'root' }, cache: { host: '192.168.1.200', username:'admin' } })
动态 import
btn.onclick = function(){ //import函数返回结果为promise对象,prmoise成功对象module为暴露的对象 import('./hello.js').then(module => { module.hello(); }); }
import * as m1 from "./hello.js";
BigInt
//大整形 let n = 521n; console.log(n, typeof(n)); //函数 let n = 123; //将整形变为大整形 console.log(BigInt(n)); //不能变整形 console.log(BigInt(1.2)); //大数值运算 //最大安全整数 let max = Number.MAX_SAFE_INTEGER; console.log(max); console.log(max + 1); console.log(max + 2); console.log(BigInt(max)) console.log(BigInt(max) + BigInt(1)) console.log(BigInt(max) + BigInt(2))
globalThis
console.log(globalThis);