ES6

145 阅读3分钟

ES6新增API语法

ES6新增语法

新增异步处理的操作

  • 异步的理解

    • 宿主环境:浏览器环境/Node环境
    • 我们写了一段JS代码时,浏览器或Node环境传递给JS引擎,并且要求他们去执行,所以JS引擎会常驻在内存中,等待宿主环境(我们)把JS代码传递给他去执行
    • ES3及其之前JS本身没有能力执行异步代码,宿主环境将代码传递给JS引擎,JS引擎就顺次执行下去,这个任务是宿主发起的
    • ES5之后,JS引入了Promise,不需要宿主环境安排,JS引擎本身也就可以发起任务
      • 宿主发起的任务称之为:宏任务
      • JS引擎发起的任务称之为:微任务
    • 理解:JS语言本身是没有异步处理的能力,是宿主环境(浏览器,nodeJS)处理了异步的操作
  • 事件循环:

    • JS引擎等待宿主环境分配宏任务,在操作系统中,等待的行为都是一个事件循环,所以在Node术语这一部分称之为:事件循环

Promise

const promise = new Promise(
(resolve,reject)=>{
        resolve('你好promise')
    }
)
promise.then((res)=>{console.log(res)}); //'你好promise
'
  1. 是一个构造函数,需要通过new Promise调用,返还一个Promise对象
    • 构造函数Promise((resolve,reject)={})有一个参数
      • 调用resolve(res);则返回一个成功的Promise对象
      • 调用reject(res);则返回一个失败的Promise对象
  2. 返回的Promise对象有.then(resolver,rejector)方法,
    • resolver(res) res为new Promise((resolve)=>{resolve(res)})
    • rejector(res) res为new Promise((resolve,reject)=>{reject(res)})
  • 特征:
    1. new Promise(()={//同步代码})
    2. .then(()=>{//异步代码,微任务},()=>{})

generator

参考:ruanyifeng_es6

function* foo(){
	yield 'hello';
	yield 'world';
	return 'ending';
}

let t = foo();
t.next(); //{value: 'hello', done: false}
t.next(); //{value: 'world', done: false}
t.next(); //{value: 'ending', done: true}
t.next(); //{value: 'undefined', done: true}

generator函数知识点:

  1. generator函数是一个状态机。
  2. 调用generator函数只返回遍历器对象(Interator Object),不返回结果
  3. 返回的遍历器对象调用next方法,开始执行yield 后面的表达式,返回{value: ‘hello’, done: false};直到遇到下一个yield或return停止执行。
  4. 第二次调用t.next(),从上一次停下来的地方开始执行下一个yield后的表达式’world’,返回yield后表达式的结果{value: ‘world’, done: false};以此类推
  5. generator函数是分段执行的,函数是可以暂停执行的函数 (遇到yield就暂停执行);next恢复执行
function* foo(x) {
  let y = 2 * (yield (x + 1));
  let z = yield (y / 3);
  return (x + y + z);
};
let it = foo(5);
console.log('it', it);
console.log(it.next()); //{value: 6, done: false}
console.log(it.next(12)); 
console.log(it.next(13)); 

generator函数数据交换:

异步的终极解决方案async await

  • 就是generator加上Promise的语法糖
  • 封装了generator的执行器和返回一个Promise
  • 返回的是一个Promise
  • await后面【表达式】的可以是一个Promise也可以是一个值,但是最终都转换成resolved的Promise;
  • await 下面的代码相当于Promise的then里的代码
  • 区别generator:内置了执行器,而且语义上更好理解,将异步函数以普通同步函数的方式书写。generator需要next函数触发执行
function sleep (sec) {
    return new Promise((resolve,reject)=>{setTimeout(resolve,sec)})
};
sleep(2000).then(()=>{console.log('hello')})


async sleep (sec) {
   console.log('hello');
   await sleep(3000);
   console.log('world');
}
async function async1() {
  console.log('async1 start')
  await async2() //等async2执行完毕,会阻塞后面的代码,跳出async函数,执行其他代码
  console.log('async1 end') //放入到Promise.then中的代码
}

async function async2() {
  console.log('async2')
}

console.log('script start')
setTimeout(function () {
  console.log('setTimeout')
}, 0)

async1();

new Promise(function (resolve) {
  console.log('promise1')
  resolve();
}).then(function () {
  console.log('promise2')
})

console.log('script end')

    /*
    同:‘script start’ ‘async1 start’ ‘async2’ promise1 ‘script end’
    宏:‘setTimeout’
    微:‘async1 end’ ‘promise2’
    */

实操案例

//实现一个红绿灯,把一个圆形div按照绿色3秒,黄色1秒,红色2秒循环改变背景色

    <style>
      #test {
        border: 20px;
        width: 100px;
        height: 100px;
        background-color: #ccc;
        border-radius: 50%;
      }
    </style>  


<body>
    <div id="test"></div>
    <script>
      const light = document.getElementById( 'test' );
      console.log( light );
      function sleep( sec ) {
        return new Promise( ( resolve, reject ) => {
          setTimeout( resolve, sec );
        } )
      };
      async function shineLight() {
        while ( 1 )
        {
          light.style.backgroundColor = 'green';
          await sleep( 3000 );
          light.style.backgroundColor = 'yellow';
          await sleep( 1000 );
          light.style.backgroundColor = 'red';
          await sleep( 2000 );
        }
      }
      shineLight();
    </script>
  </body>