参考:http://es6.ruanyifeng.com/#docs/decorator
https://zhuanlan.zhihu.com/p/30487077
1.引入async:Generator函数的语法糖,返回一个Promise对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再执行函数体内后面的语句
async function getStockPriceByName(name) {
const symbol = await getStockSymbol(name);
const stockPrice = await getStockPrice(symbol);
return stockPricec;
}
getStockPriceByName('goog').then(function (result) {
console.log(result);
});
上面代码是一个获取股票报价的函数,函数前面的async关键字,表明该函数内部有异步操作。调用该函数时,会立即返回一个Promise对象。
2.引入decorator:许多面向对象的语言都有修饰器(Decorator)函数,用来修改类的行为。
类的修饰:
@testable
class MyTestableClass {
// ...
}
function testable(target) {
target.isTestable = true;
}
MyTestableClass.isTestable // true
上面代码中,@testable就是一个修饰器。它修改了MyTestableClass这个类的行为,为它加上了静态属性isTestable。testable函数的参数target是MyTestableClass类本身。
方法的修饰:修饰器不仅可以修饰类,还可以修饰类的属性。
class Math {
@log
add(a, b) {
return a + b;
}
}
function log(target, name, descriptor) {
var oldValue = descriptor.value;
descriptor.value = function() {
console.log(`Calling ${name} with`, arguments);
return oldValue.apply(null, arguments);
};
return descriptor;
}
const math = new Math();
math.add(2, 4)
上面代码中,@log修饰器的作用就是在执行原始的操作之前,执行一次console.log,从而达到输出日志的目的。
修饰器不能用于函数。
core-decorators.js是一个第三方模块,提供几个常见的修饰器,通过它可以更好地理解修饰器:@autobind、@readonly、@override、@deprecate、@suppressWarnings
使用修饰器实现自动发布事件
const postal = require("postal/lib/postal.lodash");
export default function publish(topic, channel) {
const channelName = channel || '/';
const msgChannel = postal.channel(channelName);
msgChannel.subscribe(topic, v => {
console.log('频道:', channelName);
console.log('事件:', topic);
console.log('数据:', v);
});
return function(target, name, descriptor) {
const fn = descriptor.value;
descriptor.value = function() {
let value = fn.apply(this, arguments);
msgChannel.publish(topic, value);
};
};
}
上面代码定义了一个名为publish的修饰器,它通过改写descriptor.value,使得原方法被调用时,会自动发出一个事件。它使用的事件“发布/订阅”库是Postal.js。
// index.js
import publish from './publish';
class FooComponent {
@publish('foo.some.message', 'component')
someMethod() {
return { my: 'data' };
}
@publish('foo.some.other')
anotherMethod() {
// ...
}
}
let foo = new FooComponent();
foo.someMethod();
foo.anotherMethod();
以后,只有调用someMethod或者anotherMethod,就会自动发出一个事件。
$ bash-node index.js
频道:component
事件:foo.some.message
数据:{ my: 'data' }
频道:/
事件:foo.some.other
数据:undefined
在修饰器的基础上,可以实现Mixin模式。
const Foo = {
foo() {
console.log('foo') }
};
Trait 也是一种修饰器,效果与Mixin类似。然后,Babel转码支持。