ES6中async的使用案例
async是什么?
官方例子 官方文档
async相当于对Generator 函数的一个语法糖
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());
};
用async函数就换成了
const asyncReadFile = async function () {
const f1 = await readFile('/etc/fstab');
const f2 = await readFile('/etc/shells');
console.log(f1.toString());
console.log(f2.toString());
};
那async与Genetator有什么区别呢?我自己的理解就是,更简单,更语义化,而且会自动执行。
(1)自动执行
我们知道
generator函数需要通过调用next()方法,才能往后执行到下一个yield,但是async函数却不需要,它能够自动向后执行。
(2) 更语义化
async和await,比起星号和yield,语义更清楚了。async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果。
(3) 更广的适用性
yield命令后面只能跟随Trunk或Promise,但是await后面除了可以是Promise,也可以是普通类型,但是这样就和同步没有任何区别了。
(4) 返回值不同
generator返回的是一个遍历器对象,而async返回的是一个Promise对象
async怎么用?
await 命令
await语句后面的 Promise 变为reject,那么整个async函数都会中断执行。
async function () {
await Promise.reject('出错了');
await Promise.resolve('hello world');
}
要知道的是async返回的是一个Promise对象,后面可以使用then方法添加回调
async function getStockPriceByName(name) {
const symbol = await getStockSymbol(name);
const stockPrice = await getStockPrice(symbol);
return stockPrice;
}
getStockPriceByName('goog').then(function (result) {
console.log(result);
});
也可以使用catch方法捕捉错误信息,然而使用时需要注意catch的一些使用方法
async function () {
try {
await Promise.reject('出错了');
} catch(e) {
}
return await Promise.resolve('hello world');
}
f()
.then(v => console.log(v))
// 如果不想因为第一个异步失败,而中断后面的异步操作
// hello world
async function () {
await Promise.reject('出错了')
.catch(e => console.log(e));
return await Promise.resolve('hello world');
}
f()
.then(v => console.log(v))
// 原因同上
// 出错了
// hello world
项目中的案例
案例背景:复合报表(项目功能之一)
复合报表是由用户来进行配置高自由度的展现报表,用户可以配置模块(组件)之间的查询条件以及共有参数、私有参数,来展示一个多功能查询,展示数据工具。
methods: {
checkAllReady() {
return new Promise((resolve, reject) => {
this.$watch(() => this.allReady && this.publicAllReady,
val => {
val ? resolve(val) : reject(val);
}, {immediate: true});
}).then(val => {
return p.resolve(val);
}).catch(e => {
console.log('组件的参数还没准备好')
})
},
async getData() {
await this.checkAllReady();
const url = this.parseApi(this.option.api);
const publicParams = this.blocks.getParams();
const id = this.option.f_id;
this.loading = true;
this.showChart = true;
api.get(url, $.extend({id},publicParams,this.getParams())).then(data => {
if (data.code) {
this.loading = false;
this.$message.error(data.msg);
this.$emit('remote-data-completed');
} else {
if (data.data.is_sync_query_mode) {
this.renderChart(data.data);
this.loading = false;
this.$emit('remote-data-completed',data);
} else {
const taskId = data.data.id;
this.getStatus(taskId);
}
}
})
}
}