async 函数的含义和用法及 async 函数与 Generator 函数 的区别是什么?

学习目标:

async 函数的含义和用法 及 async 函数与 Generator 函数的区别是什么?

学习内容:

async 函数的含义和用法 及 async 函数与 Generator 函数的区别

  1. async 函数的含义
  2. async 函数的用法
  3. async 函数的优点
  4. async 函数的优点
  5. async 函数与 Generator 函数的区别

总结:

  • 1、async 函数的含义
    async 函数是使用async关键字声明的函数。
    async 函数是AsyncFunction构造函数的实例, 并且其中允许使用await关键字。
    async和await关键字让我们可以用一种更简洁的方式写出基于Promise的异步行为,而无需刻意地链式调用promise。
    (简单的来说,一句话,async 函数就是 Generator 函数的语法糖。)

    注:
    语法糖的定义和作用
    ‌1、定义‌:语法糖是一种编程术语,指在计算机语言中添加的某种语法,这种语法对语言的功能没有影响,但能提高编程的便利性和效率。
    2‌、作用‌:提高代码的可读性,减少编程错误,使代码更加简洁易读。

    例如:

var fs = require('fs')
const readeFile = function(filename){
	return new Promise(function(resolve, reject){
		fs.readFile(fileName, function(error, data){
     		if (error) reject(error);
     		resolve(data)
	     })
	})
}
const gen = function *(){
	var a1 = yield readFile('/a1');
	var a2 = yield readFile('/a2');
	console.log(a1);
	console.log(a2);
}

使用 async 函数:

const asyncFile = async function(){
	var a1 = await readFile('/a1')
	var a2 = await readFile('/a2')
	console.log(a1);
	console.log(a2);
}

通过观察以上的两种方式的代码,我们可以发现以下结论:
async 函数就是将 Generator 函数的星号(*)替换成 async,将 yield 替换成 await

  • 2、async 函数的用法
    async 函数返回一个 Promise 对象,可以使用 then 方法指定下一步操作。
    当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,再接着执行函数体内后面的语句。
async function getByName(name){
	const name = await queryName(name)
	return name
}
getByName('aa1').then(function(res){
	console.log(res)
})

上面的例子中,前面声明了一个异步函数getByName,表示该函数内部有异步操作,调用函数时,会返回一个Promise对象。
下面是一个指定多少毫秒输出的例子:

async function timeout(aa){
	return new Promise(function(resolve){
		setTimeout(resolve, aa)
	})
}

async function print(value, aa){
	await timeout(ms)
	console.log(value, aa)
}

print('hello word', 2000)

上面指定2秒后,输出一个 ‘hello word, 2000’,可以看到在执行print函数的时候会先返回一个Promise,再等待await后面的timeout执行完后,然后再往下执行。

  • 3、async 函数的优点
    async 函数对 Generator 函数的改进,主要总结为三点:

(1)内置执行器。
Generator 函数的执行必须靠执行器,所以才有了 co 函数库,而 async 函数自带执行器。也就是说,async 函数的执行,与普通函数一模一样,只要一行。
var result = asyncReadFile();
(2)更好的语义。
async 和 await,比起星号和 yield,语义更清楚了。async 表示函数里有异步操作,await 表示紧跟在后面的表达式需要等待结果。
(3)更广的适用性。
co 函数库约定,yield 命令后面只能是 Thunk 函数或 Promise 对象,而 async 函数的 await 命令后面,可以跟 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时等同于同步操作)。

使用简介的语言来说:
1)、 async 和 await,比起星号和 yield,语义更清楚。
2)、async 表示函数里有异步操作,await 表示后面的表达式需要等待结果。
3)、yield 命令后面只能是 Thunk 函数或 Promise 对象,而await 命令后面可以跟Promise对象也可以是对象、数组、数字、字符串这些(但是等同于同步操作)

  • 4、async 函数的实现
    async 函数的实现,就是将 Generator 函数和自动执行器,包装在一个函数里。
async function fn(args){
  // ...
}
// 等同于
function fn(args){ 
  return spawn(function*() {
    // ...
  }); 
}

所有的 async 函数都可以写成上面的第二种形式,其中的 spawn 函数就是自动执行器。

function spawn(genF) {
  return new Promise(function(resolve, reject) {
    var gen = genF();
    function step(nextF) {
      try {
        var next = nextF();
      } catch(e) {
        return reject(e); 
      }
      if(next.done) {
        return resolve(next.value);
      } 
      Promise.resolve(next.value).then(function(v) {
        step(function() { return gen.next(v); });      
      }, function(e) {
        step(function() { return gen.throw(e); });
      });
    }
    step(function() { return gen.next(undefined); });
  });
}
  • 5、总结
    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 命令只能用在 async 函数之中,如果用在普通函数,就会报错。

async function dbFuc(db) {
  let docs = [{}, {}, {}];
  // 报错
  docs.forEach(function (doc) {
    await db.post(doc);
  });
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值