美文网首页
async函数

async函数

作者: 文仔CXKSNLXX | 来源:发表于2018-11-11 23:56 被阅读0次

async函数

async函数的含义

简单来说:async 函数就是 Generator 函数的语法糖
下面是两个是Generator和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);
    });
  });
};

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());
};

区别:其实就是把Generator函数的*号换成await。
改进地方:

  1. async有内置执行器,不用依靠co模块才能执行
  2. async有更好的语义,从字面上就可以知道是异步的了
  3. async有更广的适用性,co模块规定,yield命令后面只能是Thunk函数或Promise对象,而async的await命令后main可以是promise对象和原始类型的值
  4. async返回值是promise:Generator返回值是iterator,所以async可以用then进行链式调用

async的基本用法

async返回值是一个Promise对象,可以使用then方法进行链式调用,当函数执行时,遇到await命令就会先返回,直到异步操作完成后,才继续执行函数后面的内容
多种使用方法:

// 函数声明
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 () => {};

async函数返回一个Promise对象

async函数内容return语句返回值,会成为then方法回调函数的参数

async function f() {
  return 'hello world';
}

f().then(v => console.log(v))
// "hello world"

async函数内部抛出错误会导致返回的Promise对象状态变为reject。而错误会被catch方法的回调函数接受到

async function f() {
  throw new Error('出错了');
}

f().then(
  v => console.log(v),
  e => console.log(e)
)
// Error: 出错了

async函数内部,只有当所有的异步操作执行完了,才会执行then方法指定的回调函数

async function getTitle(url) {
  let response = await fetch(url);
  let html = await response.text();
  return html.match(/<title>([\s\S]+)<\/title>/i)[1];
}
getTitle('https://tc39.github.io/ecma262/').then(console.log)
// "ECMAScript 2017 Language Specification"

如上图,getTitle内部中只能当抓取页面,提取文本,匹配页面标题都执行完了才会执行then方法的console.log方法

await命令

await命令后面可以跟Promise对象或原始数据。如下面的await是跟123

async function f() {
  // 等同于
  // return 123;
  return await 123;
}

f().then(v => console.log(v))
// 123

只要异步函数中,await语句后面的Promise编程reject,那么整个函数都会中断执行。如下例子

async function f() {
  await Promise.reject('出错了');
  await Promise.resolve('hello world'); // 不会执行
}

解决方法:把可能出错的代码放进try chatch结构中,这样不管代码有没有出错,后面的代码依旧会执行。例子如下

async function f() {
  try {
    await Promise.reject('出错了');
  } catch(e) {
  }
  return await Promise.resolve('hello world');
}

f()
.then(v => console.log(v))
// hello world

async的错误处理

如果await命令后面的异步操作出错,那么等同于async函数返回的promise对象被reject
防止出错的方法是将其放进try...catch代码中。如

async function f() {
  try {
    await new Promise(function (resolve, reject) {
      throw new Error('出错了');
    });
  } catch(e) {
  }
  return await('hello world');
}

注意点

如果多个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;

另外,esm模块加载器支持顶层await,即await命令可以不放在async函数里面直接使用
当然,前提你必须使用esm加载器。
例子:

// async 函数的写法
const start = async () => {
  const res = await fetch('google.com');
  return res.text();
};

start().then(console.log);

// 顶层 await 的写法
const res = await fetch('google.com');
console.log(await res.text());

相关文章

  • async和await的使用

    async函数 什么是async函数? async函数是使用async关键字声明的函数。 mdn文档:https:...

  • JS中的async/await -- 异步隧道尽头的亮光

    async函数 简单解释async函数就是Generator函数的语法糖。 Generator函数写法 async...

  • 2018-05-22

    async 函数 1. 含义 async 函数是 Generator 函数的语法糖。async函数将Generat...

  • ES8(13)、await 和 async 的用法

    async函数是使用async关键字声明的函数。 async函数是AsyncFunction构造函数的实例, 并且...

  • async函数

    async函数 async函数的含义 简单来说:async 函数就是 Generator 函数的语法糖下面是两个是...

  • ES8-async&await

    async函数是使用async关键字声明的函数,async函数是AsyncFunction构造函数的实例,返回值是...

  • async 函数(转载)

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

  • ES7 Async/Await快速入门

    用法: 使用async 声明函数,在async函数内使用await async function xxx(){aw...

  • ES6——异步操作

    async 函数 ES2017 标准引入了 async 函数,使得异步操作变得更加方便。async 函数是什么?一...

  • async/await 原理及简单实现

    解决函数回调经历了几个阶段, Promise 对象, Generator 函数到async函数。async函数目...

网友评论

      本文标题:async函数

      本文链接:https://www.haomeiwen.com/subject/trtqfqtx.html