发布于 4年前

ES6中async的使用案例

async是什么?


官方例子 官方文档

async相当于对Generator 函数的一个语法糖

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);
    });
  });
};
const gen = function* () {
  const f1 = yield readFile('/etc/fstab');
  const f2 = yield readFile('/etc/shells');
  console.log(f1.toString());
  console.log(f2.toString());
};

用async函数就换成了

const asyncReadFile = async function () {
  const f1 = await readFile('/etc/fstab');
  const f2 = await readFile('/etc/shells');
  console.log(f1.toString());
  console.log(f2.toString());
};

那async与Genetator有什么区别呢?我自己的理解就是,更简单,更语义化,而且会自动执行。

(1)自动执行

我们知道 generator 函数需要通过调用next()方法,才能往后执行到下一个yield,但是async函数却不需要,它能够自动向后执行。

(2) 更语义化

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

(3) 更广的适用性

yield命令后面只能跟随TrunkPromise,但是await后面除了可以是Promise,也可以是普通类型,但是这样就和同步没有任何区别了。

(4) 返回值不同

generator返回的是一个遍历器对象,而async返回的是一个Promise对象

async怎么用?

await 命令

await语句后面的 Promise 变为reject,那么整个async函数都会中断执行。

async function () {
  await Promise.reject('出错了');
  await Promise.resolve('hello world'); 
}

要知道的是async返回的是一个Promise对象,后面可以使用then方法添加回调

async function getStockPriceByName(name) {
  const symbol = await getStockSymbol(name);
  const stockPrice = await getStockPrice(symbol);
  return stockPrice;
}
getStockPriceByName('goog').then(function (result) {
  console.log(result);
});

也可以使用catch方法捕捉错误信息,然而使用时需要注意catch的一些使用方法

async function () {
  try {
    await Promise.reject('出错了');
  } catch(e) {
  }
  return await Promise.resolve('hello world');
}
f()
.then(v => console.log(v))
// 如果不想因为第一个异步失败,而中断后面的异步操作
// hello world
async function () {
  await Promise.reject('出错了')
    .catch(e => console.log(e));
  return await Promise.resolve('hello world');
}
f()
.then(v => console.log(v))
// 原因同上
// 出错了
// hello world

项目中的案例

案例背景:复合报表(项目功能之一)
复合报表是由用户来进行配置高自由度的展现报表,用户可以配置模块(组件)之间的查询条件以及共有参数、私有参数,来展示一个多功能查询,展示数据工具。

methods: {
  checkAllReady() {
    return new Promise((resolve, reject) => {
      this.$watch(() => this.allReady && this.publicAllReady,
        val => {
          val ? resolve(val) : reject(val);
        }, {immediate: true});
    }).then(val => {
      return p.resolve(val);
    }).catch(e => {
      console.log('组件的参数还没准备好')
    })
  },
  async getData() {
    await this.checkAllReady();
    const url = this.parseApi(this.option.api);
    const publicParams = this.blocks.getParams();
    const id = this.option.f_id;
    this.loading = true;
    this.showChart = true;
    api.get(url, $.extend({id},publicParams,this.getParams())).then(data => {
      if (data.code) {
        this.loading = false;
        this.$message.error(data.msg);
        this.$emit('remote-data-completed');
      } else {
        if (data.data.is_sync_query_mode) {
          this.renderChart(data.data);
          this.loading = false;
          this.$emit('remote-data-completed',data);
        } else {
          const taskId = data.data.id;
          this.getStatus(taskId);
        }
      }
    })
  }
}
©2020 edoou.com   京ICP备16001874号-3