【ES6学习】— (5)异步编程async函数简介

之前学习了异步编程相关的Generator函数和Promise对象。ES7(目前处于提案阶段)中提供了更加方便的async来实现异步编程。本篇主要对async的相关知识点进行简单介绍。

JavaScript语言只有一个线程,因此如果有耗时任务必须使用异步编程,将程序分两段执行。执行耗时任务时先执行其他任务,等耗时任务执行完成在回头处理。传统上JavaScript有四种异步处理方式:

  • 回调函数
  • 事件监听
  • 发布/订阅
  • Promise对象

在ES6中新增了Generator函数用来封装异步任务从而提供完整的异步编程解决方案。在ES7中新增了async函数提供了异步编程终极解决方案。

Promise对象解决了嵌套回调的代码冗余,使得代码格式变为链式调用,简化了代码样式和逻辑,但在一定程度上也会造成Promise代码的冗余,Generator函数封装了异步任务,每个异步任务用yield标记,简化了语义,但是Generator需要指定执行器才能自动执行,否则只能手动来一步步执行,使用上有所不便。async函数解决了Generator函数的问题,并且具有更加清晰的语义。async函数很简单,下面来简单介绍下其相关内容。

一、async函数简介

简单来说,async函数是Generator的语法糖(所谓语法糖可以理解为一种更加简单实用的实现方式)。下面是Generator和async函数的对比,假设我们有两个耗时异步操作:读取文件与访问网络。

//Generator函数
var gen = function*(){
  var f1 = yield readFile('url/a.txt');
  var f2 = yield getDataFromServer("api/data");
  console.log(f1.toString());
  console.log(f2.toString());
}
//async函数
async function(){
  var f1 = await readFile('url/a.txt');
  var f2 = await getDataFromServer("api/data");
  console.log(f1.toString());
  console.log(f2.toString());

}

从结构上可以看出,与Generator函数相比,async函数就是用asycn关键字替代(* )进行函数声明。另外用await代替yield指明异步操作。 另外还有以下区别:

  • async内置执行器,只要调用就会立即执行,不同于Generator函数需要next或者co模块才会执行
  • 笔记yield与星号*, async和await具有更好的语义。async表示函数里存在异步操作,await表示紧跟其后面的表达会耗时,需要等待结果。
  • yield后必须跟Thunk函数或者Promise对象,async或者await后面可以跟Promise对象或者原始类型值
  • async函数返回Promise对象可以方便进行下一步操作。比Generator返回的Iterator简便。

async函数属于ES7而不是ES6,仍处于提案阶段,但是我们可以通过Babel转码后使用。

async函数的实现

async可以自动执行,其实就是讲Generator函数和自动执行器包装在了一个函数中。下面是ES6标准入门中async函数的实现代码,记录如下:

async function(args){

}
//等同于
function(args){
  return spawn(function*(){
    //
    });
}
//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);});
    });
}

二、async函数的使用与注意事项

async函数返回一个Promise对象,然后可以通过then方法添加回调函数,当函数执行遇到await时先返回,等到异步操作任务执行完成后再去执行函数体内的内容。下面是一个简单示例:

//从服务器获取数据
async function callServer(url){
    var response = await getDataFromServer(url);
    return response;
}

callServer("api/data").then(function(response){
  console.log(response);
  });

几点注意:

  • await后面的Promise对象运行结果可能是Reject,因此最好把await放在try…catch中。或者在await后的Promise末尾加catch方法。
  • await命令只能用在async函数中,不能用在普通函数中
  • await在ES6中是作为保留字存在的,因此在ES6中使用await作为标识符将会报错,ES5中不会。

以上就是关于async函数的简单介绍,总体而言无论是理解还是使用async函数都比较简单,在项目中使用起来也非常方便,配得上异步编程终极解决方案的旗号。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值