天天看点

async 异步变同步ES6 async函数

ES6 async函数

目录

  • ES6 async函数
    • 基本用法
    • async的特点
    • 使用注意点
    • 错误处理
    • 三种方法写异步
async 异步变同步ES6 async函数

基本用法

ES2017 标准引入了 async 函数,使得异步操作变得更加方便

async函数是什么?一句话,它就是Generator函数的语法糖

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('jake').then(…);

// 箭头函数
const foo = async () => {};
           

回到顶部 目录

读取两个文件:

const fs = require('fs');

const readFile = function (fileName) {
    return new Promise(function (resolve, reject) {
        fs.readFile(fileName, function (error, data) {
            if (error) return reject(error);
            resolve(data);
        });
    });
};

// Generator 函数写法
const gen = function* () {
    const f1 = yield readFile('aa');
    const f2 = yield readFile('bb');
    console.log(f1.toString());
    console.log(f2.toString());
};

// async 函数写法
const asyncFile = async function () {
  const f1 = await readFile('aa');
  const f2 = await readFile('bb');
  console.log(f1.toString());
  console.log(f2.toString());
};
           

分析async函数实现过程:

  1. 通过async关键字,表明该函数体内部是异步操作
  2. 调用该函数,遇到await就去任务队列中执行异步操作,等到异步操作完成,在执行函数体后面的语句
  3. 返回Promise对象
  4. 任何await语句后面的Promise对象变为reject状态,那么整个async函数都会中断执行

回到顶部 目录

async的特点

  1. 不需要像Generator去调用next()方法
  2. async返回的总是Promise对象,可以用then方法进行下一步操作
  3. async取代Generator函数的星号*,await取代Generator函数的yield
  4. co模块约定,yield命令后面只能是 Thunk 函数或 Promise 对象,而async函数的await命令后面,可以是 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时会自动转成立即 resolved 的 Promise 对象)

使用注意点

  1. await命令后面的Promise对象,运行结果可能是rejected,所以最好把await命令放在try…catch代码块中
  2. 多个await命令后面的异步操作,如果不存在继发关系,最好让它们同时触发
  3. await命令只能用在async函数之中,如果用在普通函数,就会报错
  4. async 函数可以保留运行堆栈

错误处理

async function myFunction() {
  try {
    await errfn();
  } catch (err) {
    console.log(err);
  }
}

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

回到顶部 目录

三种方法写异步

var p = (val, isReject) =>{
    return new Promise((res,rej) =>{
        if(isReject){
            setTimeout(rej, 1000, val);
        }else{
            setTimeout(res, 1000, val);
        }
    })
}

// Promise对象方法
var p2 = new Promise((res, rej) => {
    p('one', false).then().then(val =>{
        console.log(val)
    })
})


// Generator 函数
var genP = function* (){
    yield p('two', false);
};
var gp = genP();
gp.next().value.then(val => {
    console.log(val)
});


// async 函数
var asyncP = async function(){
    var ap = await p('three', false);
    return ap;
}
asyncP().then(val =>{
    console.log(val)
})
           

回到顶部 目录

继续阅读