ES6新特性八:async函数用法实例详解


Posted in Javascript onApril 21, 2017

本文实例讲述了ES6新特性之async函数用法。分享给大家供大家参考,具体如下:

1. async 函数是什么?

node.js 版本7及之后版本才支持该函数。

可以简单的理解为他是Generator 函数的语法糖,即Generator 函数调用next() 返回的结果。

Generator 函数需要next() 或执行器进行执行,而async 函数只需和普通函数一样执行。

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

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

2. async 函数与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());
};
var asyncReadFile = async function () {
 var f1 = await readFile('/etc/fstab');
 var f2 = await readFile('/etc/shells');
 console.log(f1.toString());
 console.log(f2.toString());
};

3. async 函数的作用?

在异步程序中(比如在nodejs),在下一步程序中,需要异步返回的结果,由于是异步,下一步会在异步返回前就会执行完,这时程序就会出现不是我们预想的结果。而async 函数就可以很好的解决这一问题。我们将异步操作放在await 后面,等待异步返回了结果程序才会向下执行。

举例:

/**
 * Created by Dason on 2017/3/12.
 */
var mysql = require('mysql');
var pool = mysql.createPool({
 host : '127.0.0.1' ,
 user : 'root' ,
 password : 'root' ,
 database : 'dason',
 multipleStatements: true
});
//查询所有id的方法
var getResult = function () {
 return new Promise(function(resolve,reject){
  pool.getConnection(function(err,connection){
   if(err){
    console.log(err);
    throw err;
   }
   connection.query('SELECT id FROM user',function(err,result){
    if(err){
     //console.log(err);
     throw err;
     //reject(err);
    }
    console.log(result);
    //[{id:1},{id:2},{id:4},{id:5},{id:6},{id:3},{id:7}]
    connection.release();
    resolve(result);
   });
  });
 });
};
//将所有人的name 改为 A
var updateName = function(id) {
 pool.getConnection(function(err,connection){
  if(err){
   console.log(err);
  }
  connection.query("update user set name='A' where id = ?",[id],function(err,result){
   if(err){
    console.log(err);
   }
   connection.release();
  });
 });
};
async function update() {
 /**
  * getResult 是一个异步函数,放在await 后面,
  * 当函数执行的时候,一旦遇到await就会先返回,
  * 等到异步操作完成,将异步结果返回,再接着执行函数体内后面的语句。
  */
 var result = await getResult();
 console.log("result:"+JSON.stringify(result));
 //result:[{"id":1},{"id":2},{"id":4},{"id":5},{"id":6},{"id":3},{"id":7}]
 for(const obj of result){
  updateName(obj.id);
 }
}
update();// async函数调用和普通方法一样

4. 语法

① async 函数返回一个promise 对象。

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

③ async函数的await命令后面,可以是Promise 对象和原始类型的值(数值、字符串和布尔值,但这时等同于同步操作),如果不是Promise 对象,会被转成一个立即resolve的 Promise 对象。

async function f() {
 return 'hello world';//会自动调用Promise.resolve('hello world'),将其转化为promise对象
}
f().then(v => console.log(v))
// "hello world"
async function f() {
 throw new Error('出错了');
}
f().then(
 v => console.log(v),
 e => console.log(e)
)
// Error: 出错了

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

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

async function main() {
 try {
 var val1 = await firstStep();
 var val2 = await secondStep(val1);
 var val3 = await thirdStep(val1, val2);
 console.log('Final: ', val3);
 }
 catch (err) {
 console.error(err);
 }
}

⑤ await命令后面的 Promise 对象如果变为reject状态,则reject的参数会被catch方法的回调函数接收到。

async function f() {
 await Promise.reject('出错了');//没有return,即不是async函数返回的promise对象,也会被catch方法的回调函数接收到
}
f()
.then(v => console.log(v))
.catch(e => console.log(e))
// 出错了

注意2:多个await命令后面的异步操作,如果不存在继发关系,最好让它们同时触发。不然会增加耗时。

//耗时写法
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;

希望本文所述对大家ECMAScript程序设计有所帮助。

Javascript 相关文章推荐
使用javascript实现ListBox左右全选,单选,多选,全请
Nov 07 Javascript
jQuery 滑动方法slideDown向下滑动元素
Jan 16 Javascript
使用原生JS实现弹出层特效
Dec 22 Javascript
jQuery性能优化技巧分析
Feb 20 Javascript
JavaScript中几种排序算法的简单实现
Jul 29 Javascript
深入学习jQuery Validate表单验证(二)
Jan 18 Javascript
JavaScript学习笔记之数组去重
Mar 23 Javascript
JS产生随机数的用法小结
Dec 10 Javascript
JavaScript切换搜索引擎的导航网页搜索框实例代码
Jun 11 Javascript
JavaScript中call和apply方法的区别实例分析
Aug 03 Javascript
vue.draggable实现表格拖拽排序效果
Dec 01 Javascript
Vue表单绑定的实例代码(单选按钮,选择框(单选时,多选时,用 v-for 渲染的动态选项)
May 13 Javascript
.net MVC+Bootstrap下使用localResizeIMG上传图片
Apr 21 #Javascript
jquery中$.fn和图片滚动效果实现的必备知识总结
Apr 21 #jQuery
ES6新特性七:数组的扩充详解
Apr 21 #Javascript
React中ES5与ES6写法的区别总结
Apr 21 #Javascript
ES6新特性六:promise对象实例详解
Apr 21 #Javascript
ES6新特性五:Set与Map的数据结构实例分析
Apr 21 #Javascript
webpack配置的最佳实践分享
Apr 21 #Javascript
You might like
我用php+mysql写的留言本
2006/10/09 PHP
新页面打开实际尺寸的图片
2006/08/25 Javascript
Javascript 入门基础学习
2010/03/10 Javascript
jquer之ajaxQueue简单实现代码
2011/09/15 Javascript
jQuery 图片切换插件(代码比较少)
2012/05/07 Javascript
jQuery实现瀑布流布局
2014/12/12 Javascript
angularJS中router的使用指南
2015/02/09 Javascript
基于PHP和Mysql相结合使用jqGrid读取数据并显示
2015/12/02 Javascript
详解JavaScript基于面向对象之继承
2015/12/13 Javascript
javascript宿主对象之window.navigator详解
2016/09/07 Javascript
微信小程序  modal详解及实例代码
2016/11/09 Javascript
jQuery中.attr()和.data()的区别分析
2017/09/03 jQuery
JavaScript中Array方法你该知道的正确打开方法
2018/09/11 Javascript
Vue源码中要const _toStr = Object.prototype.toString的原因分析
2018/12/09 Javascript
使用Python编写vim插件的简单示例
2015/04/17 Python
python实现将文本转换成语音的方法
2015/05/28 Python
Python的Django框架中settings文件的部署建议
2015/05/30 Python
详解 Python中LEGB和闭包及装饰器
2017/08/03 Python
python DataFrame 修改列的顺序实例
2018/04/10 Python
Python实现读取字符串按列分配后按行输出示例
2018/04/17 Python
Python3爬取英雄联盟英雄皮肤大图实例代码
2018/11/14 Python
Window环境下Scrapy开发环境搭建
2018/11/18 Python
Python实现的登录验证系统完整案例【基于搭建的MVC框架】
2019/04/12 Python
tensorflow 查看梯度方式
2020/02/04 Python
解决python虚拟环境切换无效的问题
2020/04/30 Python
解决Keras中Embedding层masking与Concatenate层不可调和的问题
2020/06/18 Python
运行Python编写的程序方法实例
2020/10/21 Python
Maisons du Monde德国:法国家具和装饰的市场领导者
2019/07/26 全球购物
本科生个人求职自荐信
2013/09/26 职场文书
大学四年的个人自我评价
2014/01/14 职场文书
公司领导班子对照检查材料
2014/09/24 职场文书
2014年药店店长工作总结
2014/11/17 职场文书
Nginx下配置Https证书详细过程
2021/04/01 Servers
详解Java ES多节点任务的高效分发与收集实现
2021/06/30 Java/Android
Java完整实现记事本代码
2022/06/16 Java/Android
MySQL新手入门进阶语句汇总
2022/09/23 MySQL