ES6-ES11新语法之ES8
async和await:
ES6中的异步编程方案有 promise 和 生成器 函数,ES8中引入async和awair可以让异步代码像同步代码一样
async函数:
async函数的返回值为promise对象
promise对象的结果由async函数执行的返回值决定
// 声明一个async函数:在普通函数前加上async关键字。函数的返回结果是一个promise对象,它成功(fulfilled)或失败(reject)的状态由函数内返回的结果决定,如果抛出错误或者返回失败的promise那么该函数的返回值是失败的promise,如果返回返回非promise类型的值或者返回成功的promise那么该函数的返回值是成功的promise async function fn() { // 1、函数里啥也不写,返回成功的promise对象 [[PromiseState]]: "fulfilled" // return '你好' // 2、return一个字符串,返回成功的promise对象 [[PromiseState]]: "fulfilled" // return // 3、只写一个return,返回成功的promise对象 [[PromiseState]]: "fulfilled" // throw new Error('出错啦') // 4、抛出错误,返回失败的promise对象 [[PromiseState]]: "rejected" // 5、返回一个promise对象,执行resolve()返回fulfilled,执行reject()返回rejected return new Promise((resolve, reject) => { resolve('成功') // [[PromiseState]]: "fulfilled" // reject('失败') // [[PromiseState]]: "rejected" }) } let p = fn() console.log(p) p.then(data => { console.log(data) }).catch(err => { console.error(err) })
await表达式:
1、await表达式必须写在async函数中
2、await右侧的表达式一般是promise对象
3、await返回的是promise成功的值
4、await的promise失败了,就会抛出异常,需要通过 try...catch 捕获处理
const p = new Promise((resolve, reject) => { // resolve('成功啦') reject('出错啦') }) async function fn() { try { let res = await p console.log(res) } catch (err) { console.log(err) } } fn()
小案例:async和await结合读取文件:
const fs = require('fs') function get1() { return new Promise((resolve, reject) => { fs.readFile('./resources/为学.md', (err, data) => { if (err) reject(err) resolve(data) }) }) } function get2() { return new Promise((resolve, reject) => { fs.readFile('./resources/插秧诗.md', (err, data) => { if (err) reject(err) resolve(data) }) }) } function get3() { return new Promise((resolve, reject) => { fs.readFile('./resources/观书有感.md', (err, data) => { if (err) reject(err) resolve(data) }) }) } async function get() { let res1 = await get1() let res2 = await get2() let res3 = await get3() console.log(res1.toString()) console.log(res2.toString()) console.log(res3 + '') } get()
小案例:async和await搭配获取ajax数据:
1、promise封装一个简易的ajax
function ajax({ method, url }) { return new Promise((resolve, reject) => { let xhr = new XMLHttpRequest(); xhr.open(method, url); xhr.send(); xhr.onload = function () { if (xhr.readyState === 4) { if (xhr.status >= 200 && xhr.status < 300) { resolve(JSON.parse(xhr.response)); } else { reject(xhr.status); } } } }) }
2、ES6中使用promise的then方法和catch方法
var res = ajax({ method: 'get', url: 'https://api.apiopen.top/getJoke' }); res.then((data) => { console.log(data) }).catch((err) => { console.error(err) })
3、使用async和await后代码会简洁很多
async function get() { let res = await ajax({ method: 'get', url: 'https://test.91hiwork.com/auth-platform/auth/sys-role/allRole' }) let weather = await ajax({ method: 'get', url: 'https://www.tianqiapi.com/api/?version=v1&city=%E5%8C%97%E4%BA%AC&appid=23941491&appsecret=TXoD5e8P' }) console.log(res) console.log(weather) } get()
对象方法扩展:
1、Object.values():返回对象中所有可枚举属性值的数组
2、Object.entries():返回对象中自身可遍历属性 [key, value] 的数组
3、Object.getOwnPropertyDescriptors():返回指定对象所有自身属性的描述对象
const obj = { name: '孙艺珍', video: ['假如爱有天意', '摩天楼', '现在去见你'], city: ['北京', '上海'] } console.log(Object.keys(obj)) // ["name", "video", "city"] 这是ES6的方法 console.log(Object.values(obj)) // ["孙艺珍", Array(3), Array(2)] console.log(Object.entries(obj)) // [["name", "孙艺珍"], ["video", Array(3)], ["city", Array(2)]] const m = new Map(Object.entries(obj)) console.log(m) console.log(m.get('video')) // ["假如爱有天意", "摩天楼", "现在去见你"] console.log(Object.getOwnPropertyDescriptors(obj)) // 设置属性描述对象 const person = Object.create(null, { name: { value: '小明', writable: false, configurable: true, enumerable: true } }) console.log(Object.getOwnPropertyDescriptors(person))
注:对象扩展方法 Object.entries() 和 Map 对象搭配,使用 map.get() 方法可以快速获取到数据
字符串方法扩展:
1、字符串填充 string padding
// padStart() 和 padEnd() 用于补全字符串长度,第一参数是补全后字符串的长度,第二个参数是用什么字符串去补全 console.log('x'.padStart(5, 'a')) // 'aaaax' console.log('x'.padEnd(5, 'a')) // 'xaaaa' // 如果第一个参数小于等于原来字符串的长度,一定是返回原来的字符串 console.log('xxxxx'.padStart(2)) // 'xxxxx' console.log('xxxxx'.padEnd(5, 'a')) // 'xxxxx' // 如果不写第二个参数,默认用空格补全 console.log('x'.padStart(5)) // ' x' console.log('x'.padEnd(5)) // 'x ' // 第二个参数如果补全到参数一要求的长度后,剩下的参数是无效的相当于没写 console.log('x'.padStart(5, 'abcdef')) // 'abcdx' console.log('x'.padEnd(5, 'abcdef')) // 'xabcd' // 用途一:对于财务方面非常有用,为数值补全到指定位数 console.log('1'.padStart(10,'0')) // '0000000001' console.log('1'.padEnd(10,'0')) // '1000000000' console.log('0.00'.padStart(10)) // ' 0.00' console.log('10,000.00'.padStart(10)) // ' 10,000.00' console.log('15,000.00'.padStart(10)) // ' 15,000.00' // 用途二:提示字符串格式 console.log('07'.padStart(10,'YYYY-MM-DD')) // 'YYYY-MM-07' console.log('12-07'.padStart(10,'YYYY-MM-DD')) // 'YYYY-12-07'
尾逗号:
// ES8中函数的形参和实参中最后一个参数后面有逗号是合法的,而在ES6中这样是不合法的。对象和数组中的尾逗号自动忽略 // 这样的优点是在处理数据的时候不用再手动处理最后一个逗号的问题,不过语法格式化会自动将一些没有用的逗号清除掉。请注意:尾逗号不符合json格式,使用JSON.parse()解析会报错 function fn(a, b, c, d,) { console.log(d) } fn(1, 2, 3, this,)
x