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 相关文章推荐
突发奇想的一个jquery插件
Nov 19 Javascript
解决Jquery load()加载GB2312页面时出现乱码的两种方案
Sep 10 Javascript
JavaScript学习笔记之内置对象
Jan 22 Javascript
node.js+express制作网页计算器
Jan 17 Javascript
jQuery实现返回顶部功能
Feb 23 Javascript
文本框只能输入数字的js代码(含小数点)
Jul 10 Javascript
jQuery实现打开页面渐现效果示例
Jul 27 Javascript
JS基于for语句编写的九九乘法表示例
Jan 04 Javascript
jQuery插件实现弹性运动完整示例
Jul 07 jQuery
Angular7中创建组件/自定义指令/管道的方法实例详解
Apr 02 Javascript
laypage.js分页插件使用方法详解
Jul 27 Javascript
file-loader打包图片文件时路径错误输出为[object-module]的解决方法
Jan 03 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
MySQL修改密码方法总结
2008/03/25 PHP
javascript编程起步(第四课)
2007/01/10 Javascript
浅谈JavaScript编程语言的编码规范
2011/10/21 Javascript
javascript中onclick(this)用法介绍
2013/04/19 Javascript
js中replace的用法总结
2013/12/27 Javascript
浅谈js中的闭包
2015/03/16 Javascript
javascript实现根据3原色制作颜色选择器的方法
2015/07/17 Javascript
微信小程序 开发经验整理
2017/02/15 Javascript
React.js中常用的ES6写法总结(推荐)
2017/05/09 Javascript
JQuery通过后台获取数据遍历到前台的方法
2018/08/13 jQuery
小程序登录态管理的方法示例
2018/11/13 Javascript
Angular请求防抖处理第一次请求失效问题
2019/05/17 Javascript
JS实现商城秒杀倒计时功能(动态设置秒杀时间)
2019/12/12 Javascript
[04:12]第二届DOTA2亚洲邀请赛选手传记-Newbee.Sccc
2017/04/03 DOTA
详解在Python程序中使用Cookie的教程
2015/04/30 Python
解析Python中的生成器及其与迭代器的差异
2016/06/20 Python
Python使用django框架实现多人在线匿名聊天的小程序
2017/11/29 Python
Tensorflow 查看变量的值方法
2018/06/14 Python
Python爬虫设置代理IP(图文)
2018/12/23 Python
python实现udp传输图片功能
2020/03/20 Python
完美解决TensorFlow和Keras大数据量内存溢出的问题
2020/07/03 Python
python调用win32接口进行截图的示例
2020/11/11 Python
Python绘制K线图之可视化神器pyecharts的使用
2021/03/02 Python
英国男士时尚购物网站:Stuarts London
2017/10/22 全球购物
Stutterheim瑞典:瑞典高级外套时装品牌
2019/06/24 全球购物
毕业生个人的求职信范文
2013/12/03 职场文书
上课打牌的检讨书
2014/02/15 职场文书
仓管员岗位责任制
2014/02/19 职场文书
《我不是最弱小的》教学反思
2014/02/23 职场文书
求职自荐信怎么写
2014/03/06 职场文书
2015年班干部工作总结
2015/04/29 职场文书
李强优秀员工观后感
2015/06/16 职场文书
golang DNS服务器的简单实现操作
2021/04/30 Golang
详解Python魔法方法之描述符类
2021/05/26 Python
mysql聚集索引、辅助索引、覆盖索引、联合索引的使用
2022/02/12 MySQL
mysql中如何用命令创建联合唯一索引
2022/04/20 MySQL