首页 > 代码库 > es2017新特性

es2017新特性

2017年6月底es2017不期而至; 截止目前es8是ecmascript规范的第九个版本;自es2015开始ECMA协会将每年发布一个版本并将年号作为版本号;算了 直接看下es2017的新特性:

1.异步函数

ECMAScript 2017功能“ 异步函数 ”由Brian Terlson提出。其是Generator的语法糖,简单讲就是用async关键字代替了*,用await(只能在异步函数中使用)关键字代替了yield,并且不需要next调用直接全部执行换言之没有惰性求值如下

声明:async function testAsync ( ) { return.... } // 用async 声明一个异步函数

调用:testAsync ().then( result => {....} ).catch(e => {...})//此处 result 为异步函数最终返回值 也就是上面return的值 catch用法同generator一致;

await: await 命令后面是一个 Promise 对象。如果不是,会被转成一个立即resolve的 Promise 对象, 若Promise 变为reject,则整个async函数都会中断执行,并且reject的参数会被catch捕获;

接着看代码:

function add(num){
    return ++num
}
async function testAasync(num){
    let a = await add(num);
    let b = await add(a);
    if(a!==3){
        throw Error("error")
    }
    return {a,b};
}
testAasync(2).then(result =>{
    console.log(result );// {a:3,b:4}
}).catch(e=>console.log(e));
testAasync(1).then(result =>{
    console.log(result );
}).catch(e=>console.log(e));// error


//----------------------------------------------------------------------

async function testAasync(num){
  let c = await 789;//await 后面不是promise会被转成一个立即resolve的 Promise 对象
  let a = await Promise.reject(‘error‘);
  console.log("这里不会打印,下面也不会执行,reject的参数被下面catch捕获并打印");
  let b = await 123;
  return b;
}
testAasync(2).then(x=>{
  console.log(x);
}).catch( e => console.log(e) );// error

2.对象尾逗号

es2017允许函数对象的定义调用时参数可以加入尾逗号,以及json对象array对象都允许

function test(num1,num2,){}
test(1,2,);
let arr = [1,2,3,]
let obj = {a:1,b:2,}

3.String.padStart和String.padEnd

padStart:[length,string] 在字符串首位开始添加string直到满足length为止并返回新的字符串;

  1.若string+原字符串的长度大于length, 则多余string不添加;

  2.若string+原字符串的长度小于length, 则重复string,直到满足length;

padEnd: [length,string] 与padStart一致 唯一区别是在末尾添加;

console.log ( "test".padStart (8,"123456789123") )//1234test
console.log ( "test".padStart (8,"12") )//1212test
console.log ( "test".padEnd (8,"123456789123") )//test1234
console.log ( "test".padEnd (8,"12") )//test1212

 4.Object.values/Object.entries/Object.getOwnpropertyDescriptors

 

values: [obj],返回obj自身可枚举属性的属性值的集合;

  1.Symbol属性不可获取

  2.原型、继承属性不可获取

let obj = {x:65,a:89,b:1,[Symbol()]:78}
console.log(Object.values(obj))//[65,89,1]
function fn(){}
fn.prototype.c = {x:7}
fn.b = function(){};
console.log(Object.values(fn))//[Function]
var fns = new fn();
console.log(Object.values(fns))//[]

entries:[obj], 与values类似,返回的一个2元素的数组

  1.若obj为数组,2元素数组第0项为第1项在原数组所在下标

  2.若obj具有key-value的结构则2元素数组第0项为key第1项为value;

 

let obj = [1,2,3,]
console.log(Object.entries(obj))//[ [‘0‘,1], [‘1‘,2], [‘2‘,3] ]
let obj = {a:1,b:2}
console.log(Object.entries(obj))//[ [‘a‘,1], [‘b‘,2] ]

 

getOwnpropertyDescriptors: [obj],返回obj对象的属性描述符 具体应用请点击传送门

 5.共享内存、原子对象 

共享内存【详细文档】:SharedArrayBuffer(byteLength) // 接受一个可选长度作为参数,其指定共享内存大小;

  1.IsSharedArrayBuffer(o)// 判断o是否为共享数据块;

  2.SharedArrayBuffer.prototype  // 默认 不可写&不可配置%不可枚举

  3. SharedArrayBuffer.prototype.constructor // 初始值SharedArrayBuffer的内在对象,可通过指定第一个参数修改;

  4.SharedArrayBuffer.prototype.slice( start, end ) // 默认 不可写&可配置%不可枚举 ;

原子对象【详细文档】: atomics// 全局对象的原子属性的初始值。原子对象是单个普通对象

  1.原子对象不能用new及当函数调用;

  2.add /sub//加法/减法操作并返回与该运算结果对应的字节值列表 

  3and / or /xor - 进行位操作 并返回与该运算结果对应的字节值列表

  4load - 获取值

  5.wait( typedArray, index, value, timeout )//设置等待唤醒第四个参数为超时

  6.wake( typedArray, index, count )// 唤醒队列中休眠的代理

以上是基础的api 详情可点击相应的详细文档,worker多线程中最大问题就是数据有时不会及时同步也就子线程1与子线程2同事更改数据造成数据不是同步的原子能其中的作用之一就解决了这个问题先看段代码[目录结构为 index.html、js/index.js 、js/worker.js、js/worker2.js]:

//index.js:
const sharedBuffer = new SharedArrayBuffer(32); const sharedArray = new Int32Array(sharedBuffer); const w = new Worker("js/worker.js"); const w2 = new Worker("js/worker2.js"); w.postMessage(sharedBuffer); w2.postMessage(sharedBuffer); w.onmessage = function(e){ console.log(e.data,sharedArray) } w2.onmessage = function(e){ console.log(e.data,sharedArray) }
//worker.js

  self.addEventListener("message",function(e){

    const sharedArray = new Int32Array(e.data);
    for(var i=0;i<100000000;i++){
    sharedArray[0]++;
    }
    postMessage("worker ");
  })

  // worker2.js

  self.addEventListener("message",function(e){
    const sharedArray = new Int32Array(e.data);
    for(var i=0;i<100000000;i++){
    sharedArray[0]++;
    }
    postMessage("worker2");
  })

 

打印结果:

NOTE: 这个值是不稳定的;

技术分享

下面修改下代码:

// worker.js
self.addEventListener("message",function(e){ const sharedArray = new Int32Array(e.data); for(var i=0;i<100000000;i++){ Atomics.add(sharedArray,0,1) } postMessage("worker "); })
// worker2.js

  self.addEventListener("message",function(e){
    const sharedArray = new Int32Array(e.data);
    for(var i=0;i<100000000;i++){
    Atomics.add(sharedArray,0,123)
    }
    postMessage("worker2");
  })

 

打印结果如下:

NOTE: 结果也是不稳定的 但总归相差不是很大这块博主也不造哪里出问题了...

技术分享

最后再看下Atomics的睡眠与唤醒:

  // index.js
   const sharedBuffer = new SharedArrayBuffer(32); const sharedArray = new Int32Array(sharedBuffer); sharedArray[1] = 123; const w = new Worker("js/worker.js"); const w2 = new Worker("js/worker2.js"); w.postMessage(sharedBuffer); w2.postMessage(sharedBuffer);

//worker.js

  self.addEventListener("message",function(e){
    console.log("进入worker线程")
    const sharedArray = new Int32Array(e.data);
    for(var i=0;i<1000000000;i++){}
    console.log("耗时执行结束,唤醒worker2线程")
    Atomics.wake(sharedArray,1,3);
  });

 

 

  // worker2.js

  

  self.addEventListener("message",function(e){
    console.log("进入worker2线程")
    const sharedArray = new Int32Array(e.data);
    console.log("worker2唤醒之前我可以多一点事情...")
    Atomics.wait(sharedArray,1,123);
    console.log("worker2线程被唤醒")
  })

结果如下:

技术分享

补充下 原子操作不可逆也就是不能中断 ;

推荐个Dr. Axel Rauschmayer大神的Exploring ES2016 and ES2017一书 连接在这

环境问题.  

  1.共享内存 chrome 58.0+ 并启用 SharedArrayBuffer 支持

  2. babel-preset-es2017[ 不支持cnpm ] 传送门 + webpack;  

 

es2017新特性