ES7两个亮点Async和Object.observe
Javacript 6规范将在2015年6月完成,现在谈ES7是否太早了呢?其实不是,因为ES7的一些特性已经开始进入浏览器,比如Chrome,ES7和ES6在时间进度上不会像ES5和ES6那样相差很大。
Javascript 7主要亮点是在事件机制和异步编程,这两点主要体现在:
1. Object.observe使得模型和视图之间很容易同步。
2. async函数更易于异步编程,能够实现拉Pull或推Push。
这两点提高基础是因为JS6中引入了使用 => 代表函数,箭头函数如下例:
////ES5
function(x, y) { return x + 1; }
function(x, y) { return x + y; }
//ES6
X => X+1;
(x,y) => x+ y;
Object.observe
当前MVC模式在Angular.JS等冲击下已经变成了View视图和Model模型两个, 控制器由事件驱动机制替代,见 :MVI是一种Reactive MVC。
那么为什么JS不能自然支持事件通知机制呢?ES7引入了Object.observe:
var person = {};
var changesHandler = changes => console.log(changes);
Object.observe(person, changesHandler);
这样,当person的内容有更改,将自动触发changes函数,如下:
person = {
name: " jdon"
}
如果person的名称从jdon改为jdon.com:
person = {
name: " jdon.com"
}
这种name内容变化,将触发函数changes输出:
[
{
"type":"update",
"name":"name",
"oldValue: "jdon"
}
]
如果person增加内容:
person = {
name: " jdon.com"
employer: "banq"
}
激活函数输出:
[
{
"type":"new",
"name":"employer",
}
]
如果person删除内容employer,那么输出是:
[
{
"type":"delete",
"name":"employer",
"oldValue: "banq"
}
]
解除观察是:
Object.unobserve(person, changesHandler);
为了防止事件风暴,ES7使用了 Event Loop Queue + Microtasks,当事件处理器EventHandler发出改变事件给ChangeHandler以后,ChangeHandler不会排队在队列后面,而是替换当前EventHandler位置,这样在浏览器渲染页面之前完成所有事件通知:
易于异步编程
如何使得异步编程如同同步堵塞编程那么简单方便?
function getStockPrice(name) {
var symbol = getStockSymbol(name);
var price = getStockPrice(symbol);
return price;
}
这段代码中var price = getStockPrice(symbol);是一段拉取Pull,必须堵塞等到返回值。但是等待不一定要堵塞,可以如下:
getStockPrice("Devine Inc.", price => { … });
这段代码其实是推Push,价格price数据作为参数推入。但是当price进来时还需要判断,如果price值是错误error的情况如何处理:
function getStockPrice(name, cb) {
getStockSymbol(name, (error, symbol) => {
if (error) {
cb(error);
}
else {
getStockPrice(symbol, (error, price) => {
if (error) {
cb(error);
}
else {
cb(price);
}
})
}
})
}
这段代码中有多个丑陋的if error判断,我们引入promise:
promise.then(value => {…}, error => {…});
我们看看下面同步代码和异步代码的比较:
function getStockPrice(name) {
var symbol = getStockSymbol(name);
var price = getStockPrice(symbol);
return price;
}
上面是同步,下面是异步
function getStockPrice(name) {
return getStockSymbol(name).
then(symbol => getStockPrice(symbol));
}
可以看出来异步和同步代码两者完全不同,而在ES7中异步实现代码:
async function getStockPrice(name) {
var symbol = await getStockSymbol(name);
var price = await getStockPrice(symbol);
return price;
}
ES7引入了async这个定义。它等同于在ES6中使用Task.js库包的如下写法:
function* getStockPrice(name) {
var symbol = yield getStockSymbol(name);
var price = yield getStockPrice(symbol);
return price;
}
var result = spawn(getStockPrice.bind(null, "Pfizer"));
result.then(console.log, console.error);
ES7的类型如下: