ES6 async 函数详解 (十)

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

const gen = function* () {
  const f1 = yield readFile('/etc/fstab');
  const f2 = yield readFile('/etc/shells');
  console.log(f1.toString());
  console.log(f2.toString());
};

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 函数就是将 Generator 函数的星号( * )替换成 async ,将 yield 替换成 await ,仅此而已。

async 函数对 Generator 函数的改进,体现在以下四点:

(1)内置执行器。
Generator 函数的执行必须靠执行器,所以才有了 co 模块,而 async 函数自带执行器。也就是说, async 函数的执行,与普通函数一模一样,只要一行。

co 模块:co 模块是著名程序员 TJ Holowaychuk 于 2013 年 6 月发布的一个小工具,用于 Generator 函数的自动执行。
co 模块可以让你不用编写 Generator 函数的执行器。

// Generator 函数
var gen = function* () {
  var f1 = yield readFile('/etc/fstab');
  var f2 = yield readFile('/etc/shells');
  console.log(f1.toString());
  console.log(f2.toString());
};

//co模块使用
var co = require('co');
co(gen); //co 函数返回一个 Promise 对象
co(gen).then(function (){
  console.log('Generator 函数执行完成');
});

(2)更好的语义。
async 和 await ,比起星号和 yield ,语义更清楚了。 async 表示函数里有异步操作, await 表示紧跟在后面的表达式需要等待结果。
(3)更广的适用性。
co 模块约定, yield 命令后面只能是 Thunk 函数或 Promise 对象,而 async 函数的 await 命令后面,可以是 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时会自动转成立即 resolved 的 Promise 对象)。
(4)返回值是 Promise。
async 函数的返回值是 Promise 对象,这比 Generator 函数的返回值是 Iterator 对象方便多了。你可以用 then 方法指定下一步的操作。

进一步说, async 函数完全可以看作多个异步操作,包装成的一个 Promise 对象,而 await 命令就是内部 then 命令的语法糖。

1. 基本的 async 函数

// 定义一个异步函数
async function fetchData() {
    return 'Data fetched';
}

// 调用异步函数
fetchData().then(data => {
    console.log(data); // 输出: Data fetched
});

2. 使用 await 等待 Promise

// 模拟一个异步请求函数
function getUserData() {
    return new Promise(resolve => {
        setTimeout(() => resolve({ name: 'Alice' }), 1000);
    });
}

// 异步函数使用 await 等待 Promise
async function printUserData() {
    try {
        const userData = await getUserData();
        console.log(userData); // 输出: { name: 'Alice' }
    } catch (error) {
        console.error(error);
    }
}

printUserData();

3. 错误处理

// 异步函数中的错误处理
async function riskyFunction() {
    try {
        const result = await Promise.reject('An error occurred');
    } catch (error) {
        console.error(error); // 输出: An error occurred
    }
}

riskyFunction();

4. 链式 async 函数

async function asyncOperation() {
    return 'Operation completed';
}

async function chainAsyncFunctions() {
    try {
        const result1 = await asyncOperation();
        const result2 = await asyncOperation();
        console.log(result1, result2); // 输出: Operation completed Operation completed
    } catch (error) {
        console.error(error);
    }
}

chainAsyncFunctions();

5. async 函数作为事件处理函数

// 假设有一个按钮元素
const button = document.querySelector('#myButton');

// 为按钮添加点击事件处理函数
button.addEventListener('click', async event => {
    try {
        const data = await fetchData();
        console.log(data);
    } catch (error) {
        console.error(error);
    }
});

6. async 函数与 Promise.all

// 异步函数返回多个 Promise
async function fetchUsers() {
    return ["User1", "User2", "User3"];
}

async function fetchPosts() {
    return ["Post1", "Post2", "Post3"];
}

// 使用 Promise.all 并行处理多个异步操作
async function fetchAllData() {
    try {
        const [users, posts] = await Promise.all([fetchUsers(), fetchPosts()]);
        console.log(users, posts); // 输出: [ 'User1', 'User2', 'User3' ] [ 'Post1', 'Post2', 'Post3' ]
    } catch (error) {
        console.error(error);
    }
}

fetchAllData();

相关推荐

  1. ES6 async 函数详解

    2024-07-12 18:40:04       21 阅读
  2. ES6 箭头函数

    2024-07-12 18:40:04       53 阅读
  3. ES6 剩余函数

    2024-07-12 18:40:04       54 阅读
  4. ES6 => 箭头函数

    2024-07-12 18:40:04       27 阅读
  5. <span style='color:red;'>ES</span><span style='color:red;'>6</span><span style='color:red;'>详解</span>

    ES6详解

    2024-07-12 18:40:04      40 阅读
  6. ES6 Reflect详解

    2024-07-12 18:40:04       50 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-12 18:40:04       66 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-12 18:40:04       70 阅读
  3. 在Django里面运行非项目文件

    2024-07-12 18:40:04       57 阅读
  4. Python语言-面向对象

    2024-07-12 18:40:04       68 阅读

热门阅读

  1. Linux下如何解压rar文件

    2024-07-12 18:40:04       24 阅读
  2. C# 建造者模式(Builder Pattern)

    2024-07-12 18:40:04       22 阅读
  3. Warning: could not connect to a running Ollama instance

    2024-07-12 18:40:04       17 阅读
  4. 大语言模型

    2024-07-12 18:40:04       19 阅读
  5. EasyExcel文档链接与使用示例

    2024-07-12 18:40:04       16 阅读
  6. html转markdown nodejs实现

    2024-07-12 18:40:04       18 阅读