ES6中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);
}
}
})
}
}
</div><div class="git"></div></article><div class="box-prev-next clearfix"> </div> <span class="cover hide" id="cover"></span><div class="modal-dialog hide-dialog" id="modal-dialog"><div class="modal-header"></div> </div> <section class="disqus-comments"></section><script> var disqus_shortname = 'forsigner';
var disqus_url = 'http://weileilei.top/ES6中aysnc-await的使用/';
(function(){
var dsq = document.createElement('script');
dsq.type = 'text/javascript';
dsq.async = true;
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script><script async="" id="dsq-count-scr" src="//forsigner.disqus.com/count.js"></script>