> 文章列表 > ES6(Generator函数异步、async、class类)

ES6(Generator函数异步、async、class类)

ES6(Generator函数异步、async、class类)

一、Generator函数异步

1. 概念:

异步:先按顺序执行同步,需要某些条件完成才能返回来继续执行的叫异步

回调函数(callback函数):把异步需要某些条件完成才能执行的效果封装在一个函数(就是回调函数)

//node中的fs模块
fs.readFile('/etc/passwd', 'utf-8', function (err, data) {if (err) throw err;console.log(data);
});

2. Generator 函数的数据交换和错误处理(不太理解)

通过next给函数中输入数据:

作为上一次异步任务的返回结果:也就是说:当前参数2就是上一次执行next继续挂起操作的返回值:yield x + 2=2:此时返回y值

function* gen(x){var y = yield x + 2;return y;
}var g = gen(1);
g.next() // { value: 3, done: false }
g.next(2) // { value: 2, done: true }

部署错误处理代码,捕获函数体外抛出的错误:

通过在函数内部设置try...catch进行捕获

函数外直接调用throw就可以被获取

function* gen(x){try {var y = yield x + 2;} catch (e){console.log(e);}return y;
}var g = gen(1);
g.next();
g.throw('出错了');
// 出错了

二、async 

1.含义

 Generator 函数的语法糖:

async函数就是将 Generator 函数的星号(*)替换成async,将yield替换成await

async函数的返回值是 Promise 对象

const fs = require('fs');const readFile = function (fileName) {return new Promise(function (resolve, reject) {fs.readFile(fileName, function(error, data) {if (error) return reject(error);resolve(data);});});
};const gen = function* () {const f1 = yield readFile('/etc/fstab');const f2 = yield readFile('/etc/shells');console.log(f1.toString());console.log(f2.toString());
};
//替换上卖弄的generator函数编译方式
const asyncReadFile = async function () {const f1 = await readFile('/etc/fstab');const f2 = await readFile('/etc/shells');console.log(f1.toString());console.log(f2.toString());
};

2.基本用法

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);
});

 函数返回 的promise对象,async内部的return语句返回值,会成为then方法回调函数的参数

async function f() {return 'hello world';
}f().then(v => console.log(v))
// "hello world"

 4. await命令

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

async function f() {// 等同于// return 123;return await 123;
}f().then(v => console.log(v))
// 123

 5. 错误处理

如果await后面的异步操作出错,那么等同于async函数返回的 Promise 对象被reject

async function f() {await new Promise(function (resolve, reject) {throw new Error('出错了');});
}f()
.then(v => console.log(v))
.catch(e => console.log(e))
// Error:出错了

await命令后面的Promise对象,运行结果可能是rejected,所以最好把await命令放在try...catch代码块中

async function f() {try {await new Promise(function (resolve, reject) {throw new Error('出错了');});} catch(e) {}return await('hello world');
}

 三、Class基本语法

1.由来

语法糖:class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法

//ES5中原型添加方法
function Point(x, y) {this.x = x;this.y = y;
}Point.prototype.toString = function () {return '(' + this.x + ', ' + this.y + ')';
};var p = new Point(1, 2);
//直接利用类
class Point {constructor(x, y) {this.x = x;this.y = y;}toString() {return '(' + this.x + ', ' + this.y + ')';}
}

类的本质就是函数:类本身就指向构造函数,使用必须通过new进行实例化 

class Point {// ...
}typeof Point // "function"
Point === Point.prototype.constructor // true
class Bar {doStuff() {console.log('stuff');}
}const b = new Bar();
b.doStuff() // "stuff"

注意:类中的方法不能枚举 

 

class Point {constructor(x, y) {// ...}toString() {// ...}
}Object.keys(Point.prototype)
// []如果上面是ES5中构造函数就可以枚举:['toString']
Object.getOwnPropertyNames(Point.prototype)
// ["constructor","toString"]

2. constructor() 方法

constructor()方法是类的默认方法,类必须有constructor()方法

class Point {
}// 等同于
class Point {constructor() {}
}

 3. 静态方法

类中添加方法时候前面存在static:表示是静态方法,不会被实例继承

class Foo {static classMethod() {return 'hello';}
}Foo.classMethod() // 'hello'var foo = new Foo();
foo.classMethod()
// TypeError: foo.classMethod is not a function

4.类的继承

 通过extends关键字实现继承,让子类继承父类的属性和方法

class Point {
}class ColorPoint extends Point {
}

super在这里表示父类的构造函数,用来新建一个父类的实例对象

class Point { /* ... */ }class ColorPoint extends Point {constructor(x, y, color) {super(x, y); // 调用父类的constructor(x, y)this.color = color;}toString() {return this.color + ' ' + super.toString(); // 调用父类的toString()}
}

必须在constructor()方法中调用super(),否则就会报错

如果不调用super()方法,子类就得不到自己的this对象。

class Point {constructor(x, y) {this.x = x;this.y = y;}
}class ColorPoint extends Point {constructor(x, y, color) {this.color = color; // ReferenceErrorsuper(x, y);this.color = color; // 正确}
}