谈谈ES6语法(汇总下篇)

时间:2022-07-26
本文章向大家介绍谈谈ES6语法(汇总下篇),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

本次的ES6语法的汇总总共分为上、中、下三篇,本篇文章为下篇。

往期系列文章:

客套话不多说了,直奔下篇的内容~

async函数

ES2017标准引入了async函数,使得异步操作更加方便。async函数是Generator函数的语法糖。不打算写Generator函数,感兴趣的话可以看文档。与Generator返回值(Iterator对象)不同,async返回的是一个Promise对象。

用法

async函数返回一个Promise对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句

async function getStockPriceByName(name) {
	const symbol = await getStockSymbol(name);
	const stockPrice = await getStockPrice(symbol);
	return stockPrice;
}
getStockPriceByName('goog').then(function(result) {
	console.log(result);
})
复制代码

再来看几种情况加深下印象:

function fun1() {
  console.log('fun1');
  return 'fun1 result';
}
async function test() {
  const result1 = await fun1();
  console.log(result1);
  console.log('end');
}
test();
// 输出 
// 'fun1'
// 'fun1 result'
// 'end'
复制代码
async function fun2() {
  console.log('fun2');
  return 'fun2 result';
}
async function test() {
  const result2 = await fun2();
  console.log(result2);
  console.log('end');
}
test();
// 输出
// 'fun2'
// 'fun2 result'
// 'end'
复制代码

正常情况下,await命令后面是一个Promise对象,返回该对象的结果。如果不是Promise对象,就直接返回对应的值。

async function fun3() {
  console.log('fun3');
  setTimeout(function() {
    console.log('fun3 async');
    return 'fun3 result';
  }, 1000)
}
async function test() {
  const result3 = await fun3();
  console.log(result3);
  console.log('end');
}
test();
// 输出
// 'fun3'
// undefined
// 'end'
// 'fun3 async'
复制代码
async function fun4() {
  console.log('fun4');
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log('fun4 async');
      resolve('fun4 result');
    }, 1000);
  })
}
async function test() {
  console.log(result4);
  console.log('fun4 sync');
  console.log('end');
}
test();
// 输出
// 'fun4'
// 'fun4 async'
// 'fun4 result'
// 'fun4 sync'
// 'end'
复制代码

模拟sleep

JavaScript一直没有休眠的语法,但是借助await命令就可以让程序停顿指定的时间。【await要配合async来实现】

function sleep(interval) {
	return new Promise(resolve => {
		setTimeout(resolve, interval);
	})
}
// use
async function one2FiveInAsync() {
	for(let i = 1; i <= 5; i++) {
		console.log(i);
		await sleep(1000);
	}
}
one2FiveInAsync();
// 1, 2, 3, 4, 5 每隔一秒输出数字
复制代码

一道题

需求:使用async await改写下面的代码,使得输出的期望结果是每隔一秒输出0, 1, 2, 3, 4, 5,其中i < 5条件不能变。

for(var i = 0 ; i < 5; i++){
    setTimeout(function(){
        console.log(i);
    },1000)
}
console.log(i);
复制代码

之前我们讲过了用promise的方式实现,这次我们用async await方式来实现:

const sleep = (time) => new Promise((resolve) => {
	setTimeout(resolve, time);
});

(async () => {
	for(var i = 0; i < 5; i++){
		console.log(i);
		await sleep(1000);
	}
	console.log(i);
})();
// 符合条件的输出 0, 1, 2, 3, 4, 5
复制代码

比较promise和async

为什么只比较promiseasync呢?因为这两个用得频繁,实在的才是需要的,而且async语法generator的语法糖,generator的说法直接戳async与其他异步处理方法的比较

两者上,async语法写法上代码量少,错误处理能力佳,而且更有逻辑语义化。

假定某个 DOM 元素上面,部署了一系列的动画,前一个动画结束,才能开始后一个。如果当中有一个动画出错,就不再往下执行,返回上一个成功执行的动画的返回值。

// promise
function chainAnimationsPromise(elem, animations) {

  // 变量ret用来保存上一个动画的返回值
  let ret = null;

  // 新建一个空的Promise
  let p = Promise.resolve();

  // 使用then方法,添加所有动画
  for(let anim of animations) {
    p = p.then(function(val) {
      ret = val;
      return anim(elem);
    });
  }

  // 返回一个部署了错误捕捉机制的Promise
  return p.catch(function(e) {
    /* 忽略错误,继续执行 */
  }).then(function() {
    return ret;
  });

}
复制代码
// async await
async function chainAnimationsAsync(elem, animations) {
  let ret = null;
  try {
    for(let anim of animations) {
      ret = await anim(elem);
    }
  } catch(e) {
    /* 忽略错误,继续执行 */
  }
  return ret;
}
复制代码

类class

ES6之前,是使用构造函数来模拟类的,现在有了关键字class了,甚是开心