服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服务器之家 - 编程语言 - JavaScript - js教程 - Async、Await的实现原理,你学会了吗?

Async、Await的实现原理,你学会了吗?

2024-03-12 15:30海燕技术栈 js教程

在 async/await​ 的实现中,await​ 操作符通过生成器的暂停和恢复机制来实现异步操作的等待和执行。当遇到 await 操作符时,生成器会暂停执行并返回一个 Promise 对象。

介绍

理解async/await的实现原理需要先了解JavaScript的异步编程模型、Promise以及async/await的语法糖实现。我将逐步介绍这些概念,然后深入讨论async/await的底层实现。

1. JavaScript的异步编程模型

JavaScript是单线程语言,意味着它一次只能执行一个任务。然而,在Web开发中,有很多任务是需要异步执行的,比如网络请求、文件读写等。为了解决这个问题,JavaScript引入了回调函数、事件监听和Promise等机制来处理异步操作。

2. Promise

Promise是一种用于处理异步操作的对象,它代表了一个异步操作的最终完成或失败,并且可以获取其结果。Promise有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。Promise实例具有then()方法,可以为成功和失败状态绑定回调函数。

3. async/await的语法糖

async/await是ES2017中引入的语法糖,用于简化Promise的使用,使异步代码更易读、易写。async函数声明用于定义异步函数,而await操作符用于等待一个Promise对象的解决。

4. async/await的实现

在理解 async/await 的实现原理时,可以涉及到一些与之相关的概念,比如生成器(generator)、Thunk 函数以及 co 函数等。下面我将简要介绍这些概念,并说明它们与 async/await 的实现之间的关系。

1. 生成器(Generator)

生成器是一种特殊的函数,它可以在执行过程中暂停,并且可以在暂停的状态中与外部代码交换数据。生成器使用 function* 关键字定义,内部使用 yield 关键字来指示暂停点。

function* generatorFunction() {
  yield 1;
  yield 2;
  yield 3;
}


const generator = generatorFunction();


console.log(generator.next()); // { value: 1, done: false }
console.log(generator.next()); // { value: 2, done: false }
console.log(generator.next()); // { value: 3, done: false }
console.log(generator.next()); // { value: undefined, done: true }

2. Thunk 函数

Thunk 函数是一种用于实现惰性求值(Lazy Evaluation)的编程技巧,它是一个只接受回调函数作为参数的函数。在 JavaScript 中,Thunk 函数通常用于处理异步操作。

function asyncOperation(callback) {
  setTimeout(() => {
    callback(null, 'Async operation completed');
  }, 1000);
}


const thunk = function(callback) {
  asyncOperation(callback);
};


thunk(function(err, data) {
  if (err) {
    console.error(err);
  } else {
    console.log(data);
  }
});

3. co 函数

co 函数是一个用于管理生成器的库,它可以自动运行生成器并处理其中的异步操作。co 函数的实现原理是利用生成器函数的暂停和恢复特性,通过递归调用 generator.next() 来实现自动执行。

function* asyncTask() {
  const result1 = yield Promise.resolve('Result 1');
  const result2 = yield Promise.resolve('Result 2');
  return [result1, result2];
}


co(function* () {
  const results = yield asyncTask();
  console.log(results); // ['Result 1', 'Result 2']
});

4. async/await 与上述概念的关系

  • async/await 是基于生成器的语法糖,它使得异步代码的编写更加简洁和可读。
  • async 函数返回一个 Promise 对象,并且在函数内部使用了生成器的特性来实现暂停和恢复。
  • await 关键字用于暂停异步函数的执行,直到 Promise 对象被解决为止,而这种暂停和恢复的机制正是基于生成器实现的。

生成器、Thunk 函数以及 co 函数等概念为理解 async/await 的实现提供了重要的背景知识。通过深入了解这些概念,我们可以更好地理解 async/await 在 JavaScript 中的工作原理,并能更灵活地应用于实际的编程中。

  • async 函数的实现

async 函数是异步函数的声明方式,它内部使用生成器(Generator)来实现异步操作的暂停和恢复。当我们声明一个 async 函数时,实际上是在定义一个返回 Promise 对象的函数。这个函数内部的执行逻辑会被封装成一个生成器。

async function asyncFunction() {
  return 'Async operation completed';
}

上述代码等价于:

function asyncFunction() {
  return co(function* () {
    return 'Async operation completed';
  });
}

co 函数是一个用于管理生成器的库,它可以自动运行生成器并处理其中的异步操作。而在 async/await 中,这种自动运行和处理异步操作的能力被内置到了 JavaScript 语言中。

  • await 操作符的实现

await 操作符用于等待一个 Promise 对象的解决,并且只能在 async 函数内部使用。当我们在 async 函数中使用 await 操作符时,实际上是在告诉 JavaScript 引擎在这里暂停执行,直到后面的 Promise 对象被解决。

async function myAsyncFunction() {
  const result = await asyncOperation();
  console.log(result);
}

上述代码等价于:

function myAsyncFunction() {
  return co(function* () {
    const result = yield asyncOperation();
    console.log(result);
  });
}

在 async/await 的实现中,await 操作符通过生成器的暂停和恢复机制来实现异步操作的等待和执行。当遇到 await 操作符时,生成器会暂停执行并返回一个 Promise 对象。当这个 Promise 对象被解决后,生成器会恢复执行并返回 Promise 解决的值,从而实现了异步操作的等待和执行。

原文地址:https://mp.weixin.qq.com/s/-FkPxxcj3t_pRSm2OavILg

延伸 · 阅读

精彩推荐
  • js教程JavaScript设计模式之命令模式

    JavaScript设计模式之命令模式

    这篇文章主要介绍了JavaScript设计模式之命令模式,对设计模式感兴趣的同学,可以参考下...

    有梦想的咸鱼前端8222022-03-10
  • js教程一篇文章告诉你JavaScript 如何实现继承

    一篇文章告诉你JavaScript 如何实现继承

    JavaScript 在编程语言界是个特殊种类,它和其他编程语言很不一样,JavaScript 可以在运行的时候动态地改变某个变量的类型。...

    Python进阶学习交流5712022-02-19
  • js教程使用js原生实现年份轮播选择效果实例

    使用js原生实现年份轮播选择效果实例

    这篇文章主要给大家介绍了关于如何使用js原生实现年份轮播选择效果的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的...

    Hui-101811102021-12-30
  • js教程八个关于 Promise 高级用途的技巧

    八个关于 Promise 高级用途的技巧

    在js项目中,promise的使用应该是必不可少的,但我发现在同事和面试官中,很多中级以上的前端仍然坚持promiseInst.then()、promiseInst.catch()、Promise等常规用法...

    前端之神11032024-03-06
  • js教程javascript类数组的深入理解

    javascript类数组的深入理解

    这篇文章主要给大家介绍了关于javascript类数组的深入理解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋...

    ら淡然如雪11542022-02-15
  • js教程小程序实现列表倒计时功能

    小程序实现列表倒计时功能

    这篇文章主要为大家详细介绍了小程序实现列表倒计时功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    好想再胖十斤9142022-01-12
  • js教程JavaScript 实现页面滚动动画

    JavaScript 实现页面滚动动画

    这篇文章主要介绍了JavaScript 实现页面滚动动画的方法,帮助大家更好的理解和学习使用JavaScript,感兴趣的朋友可以了解下...

    前端小蜜蜂6772022-03-09
  • js教程微信小程序自定义modal弹窗组件的方法详解

    微信小程序自定义modal弹窗组件的方法详解

    这篇文章主要给大家介绍了关于微信小程序自定义modal弹窗组件的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学...

    遇见小美好12582021-12-15