es6学习笔记之Async函数基本教程


Posted in Javascript onMay 11, 2017

本文介绍的是关于es6中Async函数的相关内容,非常出来供大家参考学习,需要的朋友们下面来看看详细的介绍:

async 函数

async 函数,使得异步操作变得更加方便。它是 Generator 函数的语法糖。

Generator 函数,依次读取两个文件:

var fs = require('fs');
var readFile = function (fileName) {
 return new Promise(function (resolve, reject) {
 fs.readFile(fileName, function(error, data) {
  if (error) reject(error);
  resolve(data);
 });
 });
};
var gen = function* () {
 var f1 = yield readFile('/etc/fstab');
 var f2 = yield readFile('/etc/shells');
 console.log(f1.toString());
 console.log(f2.toString());
};

写成async函数,就是下面这样:

var asyncReadFile = async function () {
 var f1 = await readFile('/etc/fstab');
 var f2 = await readFile('/etc/shells');
 console.log(f1.toString());
 console.log(f2.toString());
};

async函数对 Generator 函数的改进,体现在以下四点:

1)内置执行器

Generator 函数的执行必须靠执行器,所以才有了co模块,而async函数自带执行器。也就是说,async函数的执行,与普通函数一模一样,只要一行。

var result = asyncReadFile();

上面的代码调用了asyncReadFile函数,然后它就会自动执行,输出最后结果。这完全不像 Generator 函数,需要调用next方法,或者用co模块,才能真正执行,得到最后结果。

2)更好的语义

async和await,比起星号和yield,语义更清楚了。async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果。

3)更广的适用性

co模块约定,yield命令后面只能是 Thunk 函数或 Promise 对象,而async函数的await命令后面,可以是Promise 对象和原始类型的值(数值、字符串和布尔值,但这时等同于同步操作)。

4)返回值是 Promise

async函数的返回值是 Promise 对象,这比 Generator 函数的返回值是 Iterator 对象方便多了。你可以用then方法指定下一步的操作。

进一步说,async函数完全可以看作多个异步操作,包装成的一个 Promise 对象,而await命令就是内部then命令的语法糖。

一、基本用法

async函数返回一个 Promise 对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。

function timeout(ms) {
 return new Promise((resolve) => {
 setTimeout(resolve, ms);
 });
}
async function asyncPrint(value, ms) {
 await timeout(ms);
 console.log(value);
}
asyncPrint('hello world', 5000);

上面代码指定5000毫秒以后,输出hello world。

由于async函数返回的是 Promise 对象,可以作为await命令的参数。所以,上面的例子也可以写成下面的形式:

async function timeout(ms) {
 await new Promise((resolve) => {
 setTimeout(resolve, ms);
 });
}
async function asyncPrint(value, ms) {
 await timeout(ms);
 console.log(value);
}
asyncPrint('hello world', 5000);

async 函数多种使用形式

// 函数声明
async function foo() {}
// 函数表达式
const foo = async function () {};
// 对象的方法
let obj = { async foo() {} };
obj.foo().then(...)
// Class 的方法
class Storage {
 constructor() {
 this.cachePromise = caches.open('avatars');
 }
 async getAvatar(name) {
 const cache = await this.cachePromise;
 return cache.match(`/avatars/${name}.jpg`);
 }
}
const storage = new Storage();
storage.getAvatar('hzzly').then(…);
// 箭头函数
const foo = async () => {};

二、语法

async函数的语法规则总体上比较简单,难点是错误处理机制。

返回 Promise 对象

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

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

Promise 对象的状态变化

async函数返回的 Promise 对象,必须等到内部所有await命令后面的 Promise 对象执行完,才会发生状态改变,除非遇到return语句或者抛出错误。也就是说,只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数。

async function getTitle(url) {
 let response = await fetch(url);
 let html = await response.text();
 return html.match(/<title>([\s\S]+)<\/title>/i)[1];
}
getTitle('https://tc39.github.io/ecma262/').then(console.log)
// "ECMAScript 2017 Language Specification"

上面代码中,函数getTitle内部有三个操作:抓取网页、取出文本、匹配页面标题。只有这三个操作全部完成,才会执行then方法里面的console.log。

三、使用注意点

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

async function myFunction() {
 try {
 await somethingThatReturnsAPromise();
 } catch (err) {
 console.log(err);
 }
}
// 另一种写法
async function myFunction() {
 await somethingThatReturnsAPromise()
 .catch(function (err) {
 console.log(err);
 };
}

多个await命令后面的异步操作,如果不存在继发关系,最好让它们同时触发。

//异步操作(即互不依赖),被写成继发关系。这样比较耗时,因为只有getFoo完成以后,才会执行getBar,完全可以让它们同时触发。
let foo = await getFoo();
let bar = await getBar();
// 写法一
let [foo, bar] = await Promise.all([getFoo(), getBar()]);
// 写法二
let fooPromise = getFoo();
let barPromise = getBar();
let foo = await fooPromise;
let bar = await barPromise;

await命令只能用在async函数之中,如果用在普通函数,就会报错。

更多关于async函数的使用例子可以点击查看这篇文章:https://3water.com/article/113475.htm

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
详解JavaScript中基于原型prototype的继承特性
May 05 Javascript
Js查找字符串中出现次数最多的字符及个数实例解析
Sep 05 Javascript
js中常用的Math方法总结
Jan 12 Javascript
ES6入门教程之let和const命令详解
May 17 Javascript
vue-router单页面路由
Jun 17 Javascript
DataTables添加额外的查询参数和删除columns等无用参数实例
Jul 04 Javascript
jquery获取transform里的值实现方法
Dec 12 jQuery
Bootstrap4如何定制自己的颜色和风格
Feb 26 Javascript
解决Vue调用springboot接口403跨域问题
Sep 02 Javascript
小程序实现图片预览裁剪插件
Nov 22 Javascript
JavaScript中关于预编译、作用域链和闭包的理解
Mar 31 Javascript
vue使用watch监听属性变化
Apr 30 Vue.js
Bootstrap模态框插件使用详解
May 11 #Javascript
canvas实现弧形可拖动进度条效果
May 11 #Javascript
es6学习笔记之Async函数的使用示例
May 11 #Javascript
Node.js安装配置图文教程
May 10 #Javascript
使用bootstrap插件实现模态框效果
May 10 #Javascript
详解Vue用axios发送post请求自动set cookie
May 10 #Javascript
Node.js 异步异常的处理与domain模块解析
May 10 #Javascript
You might like
解决中英文字符串长度问题函数
2007/01/16 PHP
PHP生成静态HTML页面最简单方法示例
2015/04/09 PHP
php实现用手机关闭计算机(电脑)的方法
2015/04/22 PHP
WordPress中Gravatar头像缓存到本地及相关优化的技巧
2015/12/19 PHP
PHP中strnatcmp()函数“自然排序算法”进行字符串比较用法分析(对比strcmp函数)
2016/01/07 PHP
用javascript实现读取txt文档的脚本
2007/07/20 Javascript
asp javascript 实现关闭窗口时保存数据的办法
2007/11/24 Javascript
理清apply(),call()的区别和关系
2011/08/14 Javascript
JQ获取动态加载的图片大小的正确方法分享
2013/11/08 Javascript
浅谈javascript实现八大排序
2015/04/27 Javascript
每天一篇javascript学习小结(基础知识)
2015/11/10 Javascript
使用jQuery在移动页面上添加按钮和给按钮添加图标
2015/12/04 Javascript
JavaScript function函数种类详解
2016/02/22 Javascript
关于JSON.parse(),JSON.stringify(),jQuery.parseJSON()的用法
2016/06/30 Javascript
AngularGauge 属性解析详解
2016/09/06 Javascript
jQuery实现简单的抽奖游戏
2017/05/05 jQuery
JavaScript实现多重继承的方法分析
2018/01/09 Javascript
vue使用v-if v-show页面闪烁,div闪现的解决方法
2018/10/12 Javascript
值得收藏的八个常用的js正则表达式
2018/10/19 Javascript
微信小程序向Java后台传输参数的方法实现
2020/12/10 Javascript
element-ui 弹窗组件封装的步骤
2021/01/22 Javascript
python将多个文本文件合并为一个文本的代码(便于搜索)
2011/03/13 Python
Python随手笔记之标准类型内建函数
2015/12/02 Python
Python使用PDFMiner解析PDF代码实例
2017/03/27 Python
Python建立Map写Excel表实例解析
2018/01/17 Python
Shoes For Crews法国官网:美国领先的防滑鞋设计和制造商
2018/01/01 全球购物
尤妮佳moony海外旗舰店:日本殿堂级纸尿裤品牌
2018/02/23 全球购物
Edwaybuy西班牙:小米在线商店
2019/12/04 全球购物
C语言中一个结构不能包含指向自己的指针吗
2012/05/25 面试题
结构和类有什么异同
2012/07/16 面试题
建筑施工员岗位职责
2013/11/26 职场文书
座谈会主持词
2014/03/20 职场文书
大学生求职简历自我评价
2015/03/02 职场文书
2015年社区民政工作总结
2015/04/21 职场文书
oracle连接ODBC sqlserver数据源的详细步骤
2021/07/25 Oracle
《LOL》“克隆大作战”久违归来 幻灵战队皮肤上线
2022/04/03 其他游戏